/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 * 
 * Modified by David Garcia for Finboot.
 *
 * Modfications: 
 * - New TagsCloud component.
 * - Custom style
 */

import clsx from 'clsx';
import React from 'react';

import { HtmlClassNameProvider, PageMetadata, ThemeClassNames } from '@docusaurus/theme-common';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useGlobalData from '@docusaurus/useGlobalData';
import BlogLayout from '@theme/BlogLayout';
import BlogListPaginator from '@theme/BlogListPaginator';
import SearchMetadata from '@theme/SearchMetadata';
import type {Props} from '@theme/BlogListPage';
import BlogPostItems from '@theme/BlogPostItems';

import { State, Tag, TagCloudProps } from '../types';
import SelectableTag from '../SelectableTag';
import styles from './styles.module.css';

class TagsCloud extends React.Component {

    constructor(public props: TagCloudProps) {

      super(props);
      this.state = {
        checkedTags: new Map(),
      } as State;
      this.handleChange = this.handleChange.bind(this);
    }
  
    handleChange(e: React.ChangeEvent<HTMLInputElement>) {
      const item = e.target.value;
      const isChecked = e.target.checked;
      this.setState(prevState=> ({ checkedTags: (prevState as State).checkedTags.set(item, isChecked) }));
    }
  
    render() {
      let { items, tags, clients} = this.props;
      const checkedTags = [...(this.state as State).checkedTags.entries()].filter(entry=>entry[1]).map(entry=>entry[0]);
      if (checkedTags.length > 0) {
        items = items.filter(item => {
          return checkedTags.every(tag => {
            const itemTags = item.content.metadata.tags.map(x => x.label);
            return itemTags.includes(tag);
          });
        }) || [];
      }
      let itemsComponent = (<BlogPostItems items={items} />);
      if (items.length === 0) {
        itemsComponent = (<div className={clsx(styles.noResults, 'noResults')}>
        <h3>There are no results for the selected tags yet.</h3>
      </div>);
      }
   
        return (
            <>
            <h1 className={clsx(styles.pageTitle)}>Guides</h1>
            <div className={clsx(styles.tags, 'tags')}>
                <div className={clsx(styles.tagsBlock, 'tagsBlock')}>
                    <h3>By client</h3>
                    {
                    clients.map(item => (
                        <SelectableTag key={item.label} name="tag" label={item.label} checked={(this.state as State).checkedTags.get(item.label)} onChange={this.handleChange} />
                    ))
                    }
                </div>
                <div className={clsx(styles.tagsBlock, 'tagsBlock')}>
                    <h3>By concept</h3>
                    {
                    tags.map(item => (
                        <SelectableTag key={item.label} name="tag" label={item.label} checked={(this.state as State).checkedTags.get(item.label)} onChange={this.handleChange} />
                    ))
                    }
                </div>
            </div>
            {itemsComponent}
            </>
        );
    }
}
 
 function BlogListPageMetadata(props: Props): JSX.Element {
   const {metadata} = props;
   const {
     siteConfig: {title: siteTitle},
   } = useDocusaurusContext();
   const {blogDescription, blogTitle, permalink} = metadata;
   const isBlogOnlyMode = permalink === '/';
   const title = isBlogOnlyMode ? siteTitle : blogTitle;
   return (
     <>
       <PageMetadata title={title} description={blogDescription} />
       <SearchMetadata tag="blog_posts_list" />
     </>
   );
 }
 
 function BlogListPageContent(props: Props): JSX.Element {
   const {metadata, items, sidebar} = props;
   const {siteConfig} = useDocusaurusContext();
   let clients : Array<Tag>;
   try {
    // @ts-ignore - siteConfig children objects are not typed
    clients = siteConfig['themeConfig']['blog']['clients'] as Array<Tag>;
   } catch (error) {
    clients = [];
  }
  const globalData = useGlobalData();
  const pluginData = globalData['docusaurus-plugin-content-blog']["default"];
  // @ts-ignore - pluginData is not typed
  const allTags = Object.values(pluginData['blogTags'] as Array<Tag>);
  const tags: Array<Tag> = allTags.filter(tag => !clients.find(rm => (tag.label === rm.label) ));
  return (
    <BlogLayout sidebar={sidebar}>
      <TagsCloud items={items} tags={tags} clients={clients}/>
      <BlogListPaginator metadata={metadata} />
    </BlogLayout>
  );
 }
 
 export default function BlogListPage(props: Props): JSX.Element {
   return (
     <HtmlClassNameProvider
       className={clsx(
         ThemeClassNames.wrapper.blogPages,
         ThemeClassNames.page.blogListPage,
       )}>
       <BlogListPageMetadata {...props} />
       <BlogListPageContent {...props} />
     </HtmlClassNameProvider>
   );
 }
 