import React, { useState } from "react";

// react-popper
import { usePopper } from "react-popper";
// headless ui
import { Listbox } from "@headlessui/react";
// icons
import { Check, ChevronDown } from "lucide-react";
// types
import { DropdownProps } from "./types";

export type CustomSelectProps = DropdownProps & {
  children: React.ReactNode;
  value: any;
  onChange: any;
};

const CustomSelect = ({
  customButtonClassName = "",
  buttonClassName = "",
  placement,
  children,
  className = "",
  customButton,
  disabled = false,
  input = false,
  label,
  maxHeight = "md",
  noChevron = false,
  onChange,
  optionsClassName = "",
  value,
  width = "auto",
}: CustomSelectProps) => {
  const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
  const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);

  const { styles, attributes } = usePopper(referenceElement, popperElement, {
    placement: placement ?? "bottom-start",
  });

  return (
    <Listbox
      as="div"
      value={value}
      onChange={onChange}
      className={`relative flex-shrink-0 text-left ${className}`}
      disabled={disabled}
    >
      <>
        {customButton ? (
          <Listbox.Button as={React.Fragment}>
            <button
              ref={setReferenceElement}
              type="button"
              className={`flex items-center justify-between gap-1 w-full text-xs ${
                disabled ? "cursor-not-allowed text-custom-text-200" : "cursor-pointer hover:bg-custom-background-80"
              }  ${customButtonClassName}`}
            >
              {customButton}
            </button>
          </Listbox.Button>
        ) : (
          <Listbox.Button as={React.Fragment}>
            <button
              ref={setReferenceElement}
              type="button"
              className={`flex items-center justify-between gap-1 w-full rounded-md border border-custom-border-300 shadow-sm duration-300 focus:outline-none ${
                input ? "px-3 py-2 text-sm" : "px-2.5 py-1 text-xs"
              } ${
                disabled ? "cursor-not-allowed text-custom-text-200" : "cursor-pointer hover:bg-custom-background-80"
              } ${buttonClassName}`}
            >
              {label}
              {!noChevron && !disabled && <ChevronDown className="h-3 w-3" aria-hidden="true" />}
            </button>
          </Listbox.Button>
        )}
      </>
      <Listbox.Options>
        <div
          className={`z-10 border border-custom-border-300 overflow-y-auto rounded-md bg-custom-background-90 text-xs shadow-custom-shadow-rg focus:outline-none my-1 ${
            maxHeight === "lg"
              ? "max-h-60"
              : maxHeight === "md"
              ? "max-h-48"
              : maxHeight === "rg"
              ? "max-h-36"
              : maxHeight === "sm"
              ? "max-h-28"
              : ""
          } ${width === "auto" ? "min-w-[8rem] whitespace-nowrap" : width} ${optionsClassName}`}
          ref={setPopperElement}
          style={styles.popper}
          {...attributes.popper}
        >
          <div className="space-y-1 p-2">{children}</div>
        </div>
      </Listbox.Options>
    </Listbox>
  );
};

type OptionProps = {
  children: React.ReactNode;
  value: any;
  className?: string;
};

const Option: React.FC<OptionProps> = ({ children, value, className }) => (
  <Listbox.Option
    value={value}
    className={({ active, selected }) =>
      `cursor-pointer select-none truncate rounded px-1 py-1.5 ${active || selected ? "bg-custom-background-80" : ""} ${
        selected ? "text-custom-text-100" : "text-custom-text-200"
      } ${className}`
    }
  >
    {({ selected }) => (
      <div className="flex items-center justify-between gap-2">
        <div className="flex items-center gap-2">{children}</div>
        {selected && <Check className="h-4 w-4 flex-shrink-0" />}
      </div>
    )}
  </Listbox.Option>
);

CustomSelect.Option = Option;

export { CustomSelect };