import {
  AutocompleteItem,
  AutocompleteProps,
  Autocomplete as BaseAutoComplete,
  MenuTriggerAction,
} from "@nextui-org/react";
import { ControllerFieldState } from "react-hook-form";
import { FaExclamationTriangle } from "react-icons/fa";
import { useEffect, useState } from "react";
import { useFilter } from "@react-aria/i18n";

import { Option, Options } from "@/types/options/options-data-types";

type CustomProps = {
  data: Options;
  fieldProps: any;
  fieldState: ControllerFieldState;
  control?: any;
  name?: string;
};

type AutoCompleteCustomProps = Omit<AutocompleteProps, "children"> & CustomProps;

function AutoCompleteSelect({
  label,
  name,
  variant = "faded",
  color,
  size,
  defaultInputValue,
  allowsCustomValue,
  allowsEmptyCollection = false,
  shouldCloseOnBlur,
  placeholder,
  description,
  menuTrigger,
  labelPlacement = "outside",
  defaultSelectedKey,
  disabledKeys,
  errorMessage,
  startContent,
  endContent,
  filterOptions,
  isReadOnly,
  isRequired,
  isInvalid,
  isDisabled,
  fullWidth,
  selectorIcon,
  clearIcon,
  showScrollIndicators,
  scrollRef,
  isClearable,
  disableAnimation,
  disableSelectorIconRotation,
  classNames = {
    base: "font-inter",
    listboxWrapper: "font-noto text-black dark:text-white",
    listbox: "font-noto text-black dark:text-white",
    popoverContent: "",
    endContentWrapper: "",
    clearButton: "text-saffron dark:text-persian-green",
    selectorButton: "",
  },
  fieldProps,
  fieldState,
  data,
}: AutoCompleteCustomProps) {
  const [currentState, setCurrentState] = useState({
    selectedKey: fieldProps?.value ? fieldProps.value.toString() : "",
    inputValue: fieldProps?.value ? fieldProps.value.toString() : "",
    items: data,
  });

  const { startsWith } = useFilter({ sensitivity: "base" });

  useEffect(() => {
    if (currentState.selectedKey !== null) {
      fieldProps.onChange &&
        fieldProps.onChange(Number(currentState.selectedKey));
    }
  }, [currentState.selectedKey, fieldProps]);

  const onSelectionChange = (key: React.Key | null) => {
    setCurrentState((prevState) => {
      let selectedItem = prevState.items.find(
        (option) => option.id === Number(key)
      );

      return {
        inputValue: selectedItem?.title || "",
        selectedKey: key,
        items: data.filter((item) =>
          startsWith(item.title, selectedItem?.title || "")
        ),
      };
    });
  };

  const onInputChange = (value: string) => {
    setCurrentState((prevState) => ({
      inputValue: value,
      selectedKey: value === "" ? null : prevState.selectedKey,
      items: data.filter((item) => startsWith(item.title, value)),
    }));
  };

  const onOpenChange = (isOpen: boolean, menuTrigger: MenuTriggerAction) => {
    if (menuTrigger === "manual" && isOpen) {
      setCurrentState((prevState) => ({
        inputValue: prevState.inputValue,
        selectedKey: prevState.selectedKey,
        items: data,
      }));
    }
  };

  return (
    <BaseAutoComplete
      allowsCustomValue={allowsCustomValue}
      allowsEmptyCollection={allowsEmptyCollection}
      classNames={classNames}
      clearIcon={clearIcon}
      color={color}
      defaultInputValue={defaultInputValue}
      defaultItems={data}
      defaultSelectedKey={defaultSelectedKey}
      description={description}
      disableAnimation={disableAnimation}
      disabledKeys={disabledKeys}
      disableSelectorIconRotation={disableSelectorIconRotation}
      endContent={endContent}
      errorMessage={
        fieldState.error ? (
          <>
            <FaExclamationTriangle className="me-1 my-auto size-3" />
            {fieldState.error.message}
          </>
        ) : (
          errorMessage
        )
      }
      filterOptions={filterOptions}
      fullWidth={fullWidth}
      inputProps={{
        classNames: {
          base: "mb-1.5 light text-black",
          label: "block text-sm font-bold tracking-tight font-inter",
          inputWrapper: "",
          innerWrapper: "",
          mainWrapper: "",
          input: `font-noto ${
            fieldState.invalid || isInvalid ? "text-black" : ""
          }`,
          clearButton: "text-saffron dark:text-persian-green",
          helperWrapper: "",
          description:
            "font-inter font-regular text-[12px] text-gray-500 leading-tight",
          errorMessage:
            "font-inter font-regular mt-0.5 text-[12px] leading-tight flex text-red-800 font-semibold tracking-tight",
        },
      }}
      inputValue={currentState.inputValue}
      isClearable={isClearable}
      isDisabled={isDisabled}
      isInvalid={fieldState.invalid ?? isInvalid}
      isReadOnly={isReadOnly}
      isRequired={isRequired}
      items={currentState.items}
      label={label}
      labelPlacement={labelPlacement}
      menuTrigger={menuTrigger}
      name={name}
      placeholder={placeholder}
      radius="sm"
      scrollRef={scrollRef}
      selectedKey={currentState.selectedKey}
      selectorIcon={selectorIcon}
      shouldCloseOnBlur={shouldCloseOnBlur}
      showScrollIndicators={showScrollIndicators}
      size={size}
      startContent={startContent}
      variant={variant}
      onInputChange={onInputChange}
      onOpenChange={onOpenChange}
      onSelectionChange={onSelectionChange}
    >
      {(optionItem: Option) => (
        <AutocompleteItem key={optionItem.id} textValue={optionItem.title}>
          {optionItem.title}
        </AutocompleteItem>
      )}
    </BaseAutoComplete>
  );
}

export default AutoCompleteSelect;
