import * as React from 'react';
import type { OmitNever } from '@assets/js-shop/helpers';

import { show_tooltip, remove_tooltip } from '@assets/components/tooltips';
import { useTheme } from '@assets/filters/common/contexts/theme';
import { useFormLayout } from '@assets/filters/common/contexts/formLayout';

export type OpenerBehaviour = {
   // If true the filter will always be rendered (for CSS transitions?)
   // Default is `false`.
   alwaysRenderChildren?: boolean;
   // Whether to close the current filter if user clicks outside the current filter.
   // Default is `true`.
   closeOnOutsideClick?: boolean;
   // Whether the opener should be hidden. (just pass child elements through)
   // Default is `false`.
   hidden?: boolean;
};

export type FilterCommonProps<T extends 'multi-choice' | 'range'> = OmitNever<{
   openerBehaviour?: OpenerBehaviour;
   withSearch?: T extends 'multi-choice' ? boolean : never;
}>;

type FilterOpenerProps = OpenerBehaviour & {
   title: React.ReactNode;
   activeFilters?: number;
   children?: React.ReactNode;
   tooltip?: string;
   isOpen?: boolean;
};

export function FilterOpener(props: FilterOpenerProps) {
   const {
      title,
      activeFilters = 0,
      children,
      alwaysRenderChildren = false,
      closeOnOutsideClick = true,
      tooltip,
      hidden = false,
      isOpen = false,
   } = props;
   const { isTopHorizontal } = useFormLayout();
   const { openByDefault } = useTheme();
   const [opened, setOpened] = React.useState((openByDefault || isOpen) && !isTopHorizontal);
   const openerRef = React.useRef<HTMLParagraphElement>(null);

   React.useEffect(() => {
      if (hidden || !closeOnOutsideClick) {
         return;
      }

      function clickListener(ev: Event) {
         if (ev.defaultPrevented) {
            return;
         }

         const closestFilterItem = (ev.target as HTMLElement).closest('.filter-item');

         if (!closestFilterItem || closestFilterItem !== openerRef.current) {
            setOpened(false);
         }
      }

      document.addEventListener('mousedown', clickListener);

      return () => void document.removeEventListener('mousedown', clickListener);
   }, [closeOnOutsideClick, hidden]);

   if (hidden) {
      return <>{children}</>;
   }

   if (!children) {
      return <p className="title-default">{title}</p>;
   }

   return (
      <div ref={openerRef} className="filter-item">
         <p
            className={`title-default filter-item-opener${opened ? ' opened' : ''}`}
            onClick={() => setOpened((prev) => !prev)}>
            <span className="name">
               {title}
               {!!tooltip && (
                  <i
                     className="tooltip"
                     data-tooltip={tooltip}
                     onMouseEnter={(e) => {
                        show_tooltip(e.target as HTMLElement, 0);
                     }}
                     onMouseLeave={() => {
                        remove_tooltip(0);
                     }}
                     dangerouslySetInnerHTML={{
                        __html: require('@assets/icons/tooltip-info.svg?raw'),
                     }}
                  />
               )}
               {activeFilters > 0 && <span className="count">{activeFilters}</span>}
            </span>
            <i dangerouslySetInnerHTML={{ __html: require('@assets/icons/caret-down.svg?raw') }} />
         </p>
         {(opened || alwaysRenderChildren) && children}
      </div>
   );
}
