import { Fragment, useState } from "react";

// headless ui
import { Menu, Transition } from "@headlessui/react";
// icons
import { CheckIcon, ChevronDownIcon } from "@heroicons/react/24/outline";
import { ChevronRightIcon, ChevronLeftIcon } from "@heroicons/react/20/solid";

type MultiLevelDropdownProps = {
  label: string;
  options: {
    id: string;
    label: string;
    value: any;
    selected?: boolean;
    children?: {
      id: string;
      label: string | JSX.Element;
      value: any;
      selected?: boolean;
      element?: JSX.Element;
    }[];
  }[];
  onSelect: (value: any) => void;
  direction?: "left" | "right";
  height?: "sm" | "md" | "rg" | "lg";
};

export const MultiLevelDropdown: React.FC<MultiLevelDropdownProps> = ({
  label,
  options,
  onSelect,
  direction = "right",
  height = "md",
}) => {
  const [openChildFor, setOpenChildFor] = useState<string | null>(null);

  return (
    <>
      <Menu as="div" className="relative z-10 inline-block text-left">
        {({ open }) => (
          <>
            <div>
              <Menu.Button
                onClick={() => setOpenChildFor(null)}
                className={`group flex items-center justify-between gap-2 rounded-md border border-custom-border-300 px-3 py-1.5 text-xs shadow-sm duration-300 focus:outline-none hover:text-custom-text-100 hover:bg-custom-background-90 ${
                  open ? "bg-custom-background-90 text-custom-text-100" : "text-custom-text-200"
                }`}
              >
                {label}
                <ChevronDownIcon className="h-3 w-3" aria-hidden="true" />
              </Menu.Button>
            </div>
            <Transition
              as={Fragment}
              enter="transition ease-out duration-100"
              enterFrom="transform opacity-0 scale-95"
              enterTo="transform opacity-100 scale-100"
              leave="transition ease-in duration-75"
              leaveFrom="transform opacity-100 scale-100"
              leaveTo="transform opacity-0 scale-95"
            >
              <Menu.Items
                static
                className="absolute right-0 z-10 mt-1 w-36 origin-top-right select-none rounded-md bg-custom-background-90 text-xs shadow-lg focus:outline-none"
              >
                {options.map((option) => (
                  <div className="relative p-1" key={option.id}>
                    <Menu.Item
                      as="button"
                      onClick={(e: any) => {
                        if (option.children) {
                          e.stopPropagation();
                          e.preventDefault();

                          if (openChildFor === option.id) setOpenChildFor(null);
                          else setOpenChildFor(option.id);
                        } else {
                          onSelect(option.value);
                        }
                      }}
                      className="w-full"
                    >
                      {({ active }) => (
                        <>
                          <div
                            className={`${
                              active || option.selected ? "bg-custom-background-80" : ""
                            } flex items-center gap-1 rounded px-1 py-1.5 text-custom-text-200 ${
                              direction === "right" ? "justify-between" : ""
                            }`}
                          >
                            {direction === "left" && option.children && (
                              <ChevronLeftIcon className="h-4 w-4" aria-hidden="true" />
                            )}
                            <span>{option.label}</span>
                            {direction === "right" && option.children && (
                              <ChevronRightIcon className="h-4 w-4" aria-hidden="true" />
                            )}
                          </div>
                        </>
                      )}
                    </Menu.Item>
                    {option.children && option.id === openChildFor && (
                      <div
                        className={`absolute top-0 w-36 origin-top-right select-none overflow-y-scroll rounded-md bg-custom-background-90 shadow-lg focus:outline-none ${
                          direction === "left"
                            ? "right-full -translate-x-1"
                            : "left-full translate-x-1"
                        } ${
                          height === "sm"
                            ? "max-h-28"
                            : height === "md"
                            ? "max-h-44"
                            : height === "rg"
                            ? "max-h-56"
                            : height === "lg"
                            ? "max-h-80"
                            : ""
                        }`}
                      >
                        <div className="space-y-1 p-1">
                          {option.children.map((child) => {
                            if (child.element) return child.element;
                            else
                              return (
                                <button
                                  key={child.id}
                                  type="button"
                                  onClick={() => onSelect(child.value)}
                                  className={`${
                                    child.selected ? "bg-custom-background-80" : ""
                                  } flex w-full items-center justify-between break-words rounded px-1 py-1.5 text-left text-custom-text-200 hover:bg-custom-background-80`}
                                >
                                  {child.label}{" "}
                                  <CheckIcon
                                    className={`h-3.5 w-3.5 opacity-0 ${
                                      child.selected ? "opacity-100" : ""
                                    }`}
                                  />
                                </button>
                              );
                          })}
                        </div>
                      </div>
                    )}
                  </div>
                ))}
              </Menu.Items>
            </Transition>
          </>
        )}
      </Menu>
    </>
  );
};
