import { cn } from "@/core/lib/utils";
import { ChevronDown, Search } from "lucide-react";
import {
  forwardRef,
  type InputHTMLAttributes,
  useEffect,
  useRef,
  useState,
} from "react";

type Option = { value: string; label: string };

type BaseDropdownProps = Omit<
  InputHTMLAttributes<HTMLInputElement>,
  "onChange"
> & {
  label?: string;
  error?: string;
  variant?: "primary" | "error";
  options: Option[];
  placeholder?: string;
  value?: string;
  onChange?: (value: string) => void;
  onInputChange?: (inputValue: string) => void;
};

export const BaseDropdown = forwardRef<HTMLDivElement, BaseDropdownProps>(
  (
    {
      label,
      error,
      variant = "primary",
      options,
      placeholder = "انتخاب کنید",
      className,
      value,
      onChange,
      disabled,
      onInputChange,
    },
    ref
  ) => {
    const [isOpen, setIsOpen] = useState(false);
    const [searchQuery, setSearchQuery] = useState("");
    const dropdownRef = useRef<HTMLDivElement>(null);
    const inputRef = useRef<HTMLInputElement>(null);

    const selectedOption = options.find((option) => option.value === value);

    useEffect(() => {
      const handleClickOutside = (event: MouseEvent) => {
        if (
          dropdownRef.current &&
          !dropdownRef.current.contains(event.target as Node)
        ) {
          setIsOpen(false);
        }
      };

      document.addEventListener("mousedown", handleClickOutside);
      return () => {
        document.removeEventListener("mousedown", handleClickOutside);
      };
    }, []);

    useEffect(() => {
      if (isOpen) {
        setTimeout(() => inputRef.current?.focus(), 0);
      }
    }, [isOpen]);

    const handleSelect = (option: Option) => {
      if (onChange) {
        onChange(option.value);
      }
      setIsOpen(false);
      setSearchQuery("");
    };

    const filteredOptions = options.filter((option) =>
      option.label.toLowerCase().includes(searchQuery.toLowerCase())
    );

    const hasError = !!error;

    return (
      <div className="w-full" ref={ref}>
        {label && (
          <label className="mb-2 block text-sm font-medium text-foreground text-right">
            {label}
          </label>
        )}

        <div className="relative" ref={dropdownRef}>
          <button
            type="button"
            disabled={disabled}
            onClick={() => setIsOpen(!isOpen)}
            className={cn(
              "flex h-12 w-full items-center justify-between rounded-lg border-2 bg-background px-4 py-2 text-sm transition-all duration-200",
              "focus-visible:outline-none focus-visible:ring-1",
              variant === "error" || hasError
                ? "border-red-500 focus-visible:border-red-500 focus-visible:ring-red-500/20"
                : "border-gray-300 focus-visible:border-blue-600 focus-visible:ring-blue-600/20",
              disabled && "opacity-60 cursor-not-allowed bg-gray-50",
              className
            )}
          >
            <span className={selectedOption ? "text-black" : "text-gray-400"}>
              {selectedOption ? selectedOption.label : placeholder}
            </span>
            <ChevronDown
              className={cn(
                "h-5 w-5 transition-transform",
                isOpen && "rotate-180",
                hasError ? "text-red-500" : "text-gray-500"
              )}
            />
          </button>

          {isOpen && (
            <div className="absolute z-10 mt-1 w-full rounded-lg border-2 border-gray-200 bg-white shadow-lg max-h-60 overflow-auto">
              <div className="p-2">
                <div className="relative">
                  <input
                    ref={inputRef}
                    type="text"
                    placeholder="جستجو..."
                    className="w-full rounded-md border border-gray-300 px-3 py-2 pl-8 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500"
                    value={searchQuery}
                    onChange={(e) => {
                      setSearchQuery(e.target.value);
                      if (onInputChange) {
                        onInputChange(e.target.value);
                      }
                    }}
                  />
                  <Search className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
                </div>
              </div>
              <ul className="max-h-48 overflow-auto">
                {filteredOptions.map((option) => (
                  <li
                    key={option.value}
                    onClick={() => handleSelect(option)}
                    className="cursor-pointer px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
                  >
                    {option.label}
                  </li>
                ))}
              </ul>
            </div>
          )}
        </div>

        {hasError && (
          <p className="mt-2 text-sm text-red-600 flex items-center gap-1 text-end">
            {error}
          </p>
        )}
      </div>
    );
  }
);

BaseDropdown.displayName = "BaseDropdown";
