import { Fragment, useState } from "react";

// headless ui
import { Menu, Transition } from "@headlessui/react";
// icons
import { 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;
    }[];
  }[];
  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 px-3 py-1.5 text-xs shadow-sm duration-300 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 ${
                open ? "bg-gray-100 text-gray-900" : "text-gray-500"
              }`}
            >
              {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-white text-xs shadow-lg ring-1 ring-black ring-opacity-5 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-gray-100" : "text-gray-900"
                          } flex items-center gap-1 rounded px-1 py-1.5 ${
                            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 && (
                    <Menu.Items
                      static
                      className={`absolute top-0 w-36 origin-top-right select-none overflow-y-scroll rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 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) => (
                          <Menu.Item
                            key={child.id}
                            as="button"
                            type="button"
                            onClick={() => {
                              onSelect(child.value);
                            }}
                            className={({ active }) =>
                              `${
                                active || child.selected ? "bg-gray-100" : "text-gray-900"
                              } flex w-full items-center break-all rounded px-1 py-1.5 text-left capitalize`
                            }
                          >
                            {child.label}
                          </Menu.Item>
                        ))}
                      </div>
                    </Menu.Items>
                  )}
                </div>
              ))}
            </Menu.Items>
          </Transition>
        </>
      )}
    </Menu>
  );
};