/* eslint jsx-a11y/click-events-have-key-events: warn */

/* eslint jsx-a11y/no-static-element-interactions: warn */
import { useOutsideClick } from '@chakra-ui/react';
import clsx from 'clsx';
import { observer } from 'mobx-react-lite';
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom';
import { twMerge } from 'tailwind-merge';

import { useStores } from '@/app/(root)/AppProviders';
import { ProjectMetadataSchema } from '@/state/projectStore';

import Button, {
  Props as ButtonProps,
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '../button/Button';

const ProjectsDropdownV2 = observer(
  ({
    value,
    onSelectProject,
    menuClassName,
    onOpenChange,
    scrollOffset,
    ...restProps
  }: {
    value: string;
    onSelectProject?: (project: ProjectMetadataSchema) => void;
    onOpenChange?: (isOpen: boolean) => void;
    menuClassName?: string;
    scrollOffset?: number;
  } & Omit<ButtonProps, 'children'>) => {
    const { project } = useStores();

    const [open, setOpen] = useState(false);
    const [query, setQuery] = useState('');
    const [topPosition, setTopPosition] = useState(0);
    const [leftPosition, setLeftPosition] = useState(0);
    const [selectedProject, setSelectedProject] = useState(
      project.projectsById[project.currentProjectId]
    );

    useEffect(() => {
      setSelectedProject(project.projectsById[project.currentProjectId]);
    }, [project.currentProjectId]);

    const buttonRef = useRef<HTMLButtonElement>(null);
    const menuRef = useRef<HTMLDivElement | null>(null);

    useOutsideClick({
      ref: menuRef as React.RefObject<HTMLDivElement>,
      handler: (e) => {
        if (
          e.target &&
          !buttonRef.current?.contains(e.target as Node) &&
          open
        ) {
          setOpen(false);
          setQuery('');
        }
      },
    });

    useEffect(() => {
      setTopPosition(
        (buttonRef.current?.getBoundingClientRect()?.top || 0) +
          (buttonRef.current?.getBoundingClientRect()?.height || 0)
      );
      setLeftPosition(
        (buttonRef.current?.getBoundingClientRect()?.left || 0) -
          260 +
          (buttonRef.current?.getBoundingClientRect()?.width || 0)
      );
    }, [scrollOffset]);

    useLayoutEffect(() => {
      const updatePosition = () => {
        if (buttonRef.current) {
          const rect = buttonRef.current.getBoundingClientRect();
          setTopPosition((rect?.top || 0) + (rect?.height || 0));
          setLeftPosition((rect?.left || 0) - 260 + (rect?.width || 0));
        }
      };

      updatePosition();

      const observer = new ResizeObserver(updatePosition);
      if (buttonRef.current) {
        observer.observe(buttonRef.current);
      }

      return () => {
        if (buttonRef.current) {
          observer.unobserve(buttonRef.current);
        }
      };
    }, []);

    return (
      <>
        <Button
          ref={buttonRef}
          shape={ButtonShape.Pill}
          size={ButtonSize.Small}
          variant={ButtonVariant.Secondary}
          {...(restProps as any)}
          onClick={() => setOpen((prev) => !prev)}
        >
          {selectedProject?.name}
          <svg
            className={clsx('inline-block h-4 w-4 transition-transform', {
              ['rotate-0']: !open,
              ['rotate-180']: open,
            })}
            xmlns='http://www.w3.org/2000/svg'
            viewBox='0 0 20 20'
            fill='currentColor'
          >
            <path
              fillRule='evenodd'
              d='M5.23 7.21a.75.75 0 011.06 0L10 10.93l3.71-3.72a.75.75 0 111.06 1.06l-4.25 4.25a.75.75 0 01-1.06 0L5.23 8.27a.75.75 0 010-1.06z'
              clipRule='evenodd'
            />
          </svg>
        </Button>

        {open &&
          ReactDOM.createPortal(
            <div
              className={twMerge(
                'absolute z-1500 flex h-auto max-h-[240px] w-[260px] flex-col gap-3 rounded-lg bg-background-secondary p-3 shadow-lg',
                menuClassName
              )}
              style={{
                top: topPosition,
                left: leftPosition,
              }}
              ref={menuRef}
            >
              <input
                type='text'
                className='flex-1 rounded-lg bg-background-primary p-2 pl-4 outline-none'
                placeholder='Search...'
                value={query}
                onChange={(e) => {
                  setQuery(e.target.value);
                }}
              />
              <div className='flex-1 overflow-y-auto'>
                {project.allProjects
                  .filter(
                    (p: ProjectMetadataSchema) =>
                      query.length === 0 ||
                      p.name.toLowerCase().includes(query.toLowerCase())
                  )
                  .map((p: ProjectMetadataSchema) => (
                    <div
                      className='flex h-auto w-full cursor-pointer flex-row rounded-md p-2 hover:bg-background-fog-thick'
                      key={p.id}
                      onClick={() => {
                        setSelectedProject(p);
                        onSelectProject?.(p);
                        setOpen(false);
                        setQuery('');
                      }}
                    >
                      <span>
                        {p.name} ({p.clip_count} clips)
                      </span>
                    </div>
                  ))}
              </div>
            </div>,
            document.body
          )}
      </>
    );
  }
);
export default ProjectsDropdownV2;
