import React, { useCallback, useState } from 'react';
import { DocsMenuProcedure } from './DocsMenuProcedure';
import './DocsMenuScopeGroup.css';
import { Link, useParams } from 'react-router-dom';
import { Button } from '@therms/atalaya';
import { useDownloadTSConvertedSchema } from '../hooks/useDownloadTSConvertedSchema';

export const DocsMenuScopeGroup = (props) => {
  const params = useParams();

  const [searchTerm, setSearchTerm] = useState('');
  const doesItMatchSearch = useCallback(
    (str) => {
        /**
         * The logic here splits the users search term into words by spaces.
         * Each word has to match the passed in string for it to be successful.
         * This allows a user to search "get details" and return true for "get-entry-list-details".
         */

      const rgxs = searchTerm.split(' ').map((term) => {
        return new RegExp(term, 'gi');
      });

      let matchedTermCount = 0

      for (const rgx of rgxs) {
        if (rgx.test(str)) matchedTermCount++;
      }

      return matchedTermCount === rgxs.length;
    },
    [searchTerm],
  );

  const handleDownloadTS = useDownloadTSConvertedSchema(
    props.rpcScopeProcedure.allProceduresByScope,
  );

  return (
    <div className="docs-menu-scope-title">
      <div className="mb-2">
        <input
          className="rounded search-bar"
          type="search"
          placeholder="Filter..."
          onChange={(event) => {
            setSearchTerm(event.target.value);
          }}
        />
      </div>

      <div className="my-1">
        <Button onClick={handleDownloadTS} subtle>
          ⬇ Download TypeScript Schema
        </Button>
      </div>

      {Object.entries(props.rpcScopeProcedure.versionsByScopeProcedure)
        .filter(([scope, scopeProcedures]) => {
          if (!searchTerm) {
            return true;
          } else {
            const scopeAndProcedures = `${scope} ${Object.keys(
              scopeProcedures,
            ).join(' ')}`;

            return doesItMatchSearch(scopeAndProcedures);
          }
        })
        .map(([scope, scopeProcedures]) => {
          const currentScope = params.scope === scope;

          return (
            <div
              className={`${currentScope ? 'bg-main-faded pb-1 rounded' : ''}`}
              key={scope}
            >
              <div className={`font-bold`}>{scope}</div>

              {Object.keys(scopeProcedures)
                .filter((procedure) => {
                  if (!searchTerm) return true;

                  return doesItMatchSearch(procedure);
                })
                .map((procedure) => {
                  const currentProcedure = params.procedure === procedure;

                  return (
                    <div
                      className={`${currentProcedure ? 'bg-main' : ''}`}
                      key={scope + procedure}
                    >
                      <Link
                        to={`/docs/${scope}/${procedure}/${scopeProcedures[procedure].length}`}
                      >
                        <DocsMenuProcedure
                          procedure={procedure}
                          key={procedure}
                        />
                      </Link>
                    </div>
                  );
                })}
            </div>
          );
        })}
    </div>
  );
};
