import './styles.scss';
import { memo, useEffect, useState, type KeyboardEvent } from 'react';
import { useCache } from './cache';
import { SectionRow } from './SectionRow';
import { AutocompleteSections } from './Autocomplete';
import type { WidgetProps } from './index';
import { WidgetPropsProvider } from './utils';

function handleKeyboardNav(ev: KeyboardEvent<HTMLDivElement>) {
   const { currentTarget } = ev;

   switch (ev.key) {
      case 'Escape':
         (currentTarget.querySelector('.form-control') as HTMLInputElement).focus();
         break;

      case 'ArrowDown':
         if (!document.activeElement?.classList.contains('section-row')) {
            const firstFocusTarget = currentTarget.querySelector('.section-row') as HTMLDivElement | undefined;
            if (!firstFocusTarget) {
               return;
            }

            firstFocusTarget.focus();
            firstFocusTarget.scrollIntoView({ behavior: 'smooth', block: 'center' });
            return;
         }

         const nextSibling = document.activeElement.nextElementSibling as HTMLDivElement | undefined;
         if (nextSibling && nextSibling.classList.contains('section-row')) {
            nextSibling.focus();
            nextSibling.scrollIntoView({ behavior: 'smooth', block: 'center' });
            return;
         }
         break;

      case 'ArrowUp':
         const prevSibling = document.activeElement?.previousElementSibling as HTMLDivElement | undefined;
         if (prevSibling && prevSibling.classList.contains('section-row')) {
            prevSibling.focus();
            prevSibling.scrollIntoView({ behavior: 'smooth', block: 'center' });
            return;
         }
         break;
   }
}

export function SectionsWidget(props: WidgetProps) {
   const [shouldShow, setShouldShow] = useState(false);
   const [value, setValue] = useState('');
   const [debouncedSearchTerm, setDebouncedSearchTerm] = useState('');
   const [cache] = useCache();

   useEffect(() => {
      function handleClick() {
         setShouldShow(false);
      }

      document.addEventListener('click', handleClick);

      return () => {
         document.removeEventListener('click', handleClick);
      }
   }, []);

   useEffect(() => {
      const timeout = setTimeout(() => setDebouncedSearchTerm(value), 300);

      return () => clearTimeout(timeout);
   }, [value]);

   return (
      <div
         onKeyUp={handleKeyboardNav}
         onKeyDown={(ev) => {
            if (ev.key === 'ArrowUp' || ev.key === 'ArrowDown') {
               ev.preventDefault();
            }
         }}
         onClick={e => {
            e.stopPropagation();
            setShouldShow(true);
         }}
      >
         <input
            onClick={() => {
               cache._fetchTopLevelSections();
               setShouldShow(true);
            }}
            type="text"
            className="form-control"
            onChange={(e) => setValue(e.target.value)}
            value={value}
            placeholder="Vyhledejte sekci"
            onFocus={() => {
               setShouldShow(true);
               setValue('');
            }}
         />
         <WidgetPropsProvider value={{...props, hide: () => setShouldShow(false), show: () => setShouldShow(true) }}>
            {shouldShow && <WidgetPopover searchTerm={debouncedSearchTerm} />}
         </WidgetPropsProvider>
      </div>
   );
}

const WidgetPopover = memo(({ searchTerm }: { searchTerm: string }) => {
   const topLevel = useCache('topLevelSections');

   return (
      <div className="autocomplete-window">
         {!searchTerm && topLevel.map((section, i) => (
            <SectionRow
               section={section}
               key={`t${section.id}-${i}`}
               hasSubsections={!!section.has_subsections}
            />
         ))}
         {!!searchTerm && <AutocompleteSections searchTerm={searchTerm} />}
      </div>
   );
});
