"use client";

import { SelectHTMLAttributes, forwardRef, useState, useRef, useEffect } from "react";

interface SelectOption {
    value: string;
    label: string;
}

interface SearchableSelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'onChange'> {
    label?: string;
    error?: string;
    helperText?: string;
    leftIcon?: string;
    options: SelectOption[];
    placeholder?: string;
    onChange?: (value: string) => void;
    value?: string;
}

const SearchableSelect = forwardRef<HTMLSelectElement, SearchableSelectProps>(
    (
        {
            label,
            error,
            helperText,
            leftIcon,
            options,
            placeholder,
            className = "",
            onChange,
            value,
            required,
            ...props
        },
        ref
    ) => {
        const [isOpen, setIsOpen] = useState(false);
        const [searchTerm, setSearchTerm] = useState("");
        const [selectedOption, setSelectedOption] = useState<SelectOption | null>(
            options.find(opt => opt.value === value) || null
        );
        const containerRef = useRef<HTMLDivElement>(null);
        const searchInputRef = useRef<HTMLInputElement>(null);

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

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

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

        useEffect(() => {
            if (isOpen && searchInputRef.current) {
                searchInputRef.current.focus();
            }
        }, [isOpen]);

        useEffect(() => {
            if (value) {
                const option = options.find(opt => opt.value === value);
                if (option) {
                    setSelectedOption(option);
                }
            }
        }, [value, options]);

        const handleSelect = (option: SelectOption) => {
            setSelectedOption(option);
            setIsOpen(false);
            setSearchTerm("");
            if (onChange) {
                onChange(option.value);
            }
        };

        return (
            <div className="w-full">
                {/* Hidden select for form compatibility */}
                <select
                    ref={ref}
                    value={selectedOption?.value || ""}
                    onChange={(e) => {
                        const option = options.find(opt => opt.value === e.target.value);
                        if (option) handleSelect(option);
                    }}
                    className="hidden"
                    required={required}
                    {...props}
                >
                    <option value="" disabled>
                        {placeholder || "Selecione uma opção"}
                    </option>
                    {options.map((option) => (
                        <option key={option.value} value={option.value}>
                            {option.label}
                        </option>
                    ))}
                </select>

                {label && (
                    <label className="block text-[13px] font-semibold text-zinc-900 dark:text-white mb-2">
                        {label}
                        {required && <span className="text-brand-500 ml-1">*</span>}
                    </label>
                )}

                <div ref={containerRef} className="relative">
                    {leftIcon && (
                        <i
                            className={`${leftIcon} absolute left-3.5 top-1/2 -translate-y-1/2 text-zinc-500 dark:text-zinc-400 text-[20px] pointer-events-none z-10`}
                        />
                    )}

                    {/* Custom trigger */}
                    <button
                        type="button"
                        onClick={() => setIsOpen(!isOpen)}
                        className={`
                            w-full px-3.5 py-3 text-[14px] font-normal
                            border rounded-md bg-white dark:bg-zinc-800
                            text-zinc-900 dark:text-white text-left
                            transition-all
                            cursor-pointer
                            ${leftIcon ? "pl-11" : ""}
                            pr-11
                            ${error
                                ? "border-red-500 focus:border-red-500"
                                : "border-zinc-200 dark:border-zinc-700 focus:border-brand-500"
                            }
                            outline-none ring-0 focus:ring-0 shadow-none focus:shadow-none
                            ${className}
                        `}
                    >
                        {selectedOption ? selectedOption.label : (
                            <span className="text-zinc-500 dark:text-zinc-400">{placeholder || "Selecione uma opção"}</span>
                        )}
                    </button>

                    <i className={`ri-arrow-${isOpen ? 'up' : 'down'}-s-line absolute right-3.5 top-1/2 -translate-y-1/2 text-zinc-500 dark:text-zinc-400 text-[20px] pointer-events-none transition-transform`} />

                    {/* Dropdown */}
                    {isOpen && (
                        <div className="absolute z-50 w-full mt-2 bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-md shadow-lg max-h-[300px] overflow-hidden">
                            {/* Search input */}
                            <div className="p-2 border-b border-zinc-200 dark:border-zinc-700">
                                <div className="relative">
                                    <i className="ri-search-line absolute left-3 top-1/2 -translate-y-1/2 text-zinc-500 dark:text-zinc-400 text-[16px]" />
                                    <input
                                        ref={searchInputRef}
                                        type="text"
                                        value={searchTerm}
                                        onChange={(e) => setSearchTerm(e.target.value)}
                                        placeholder="Buscar..."
                                        className="w-full pl-9 pr-3 py-2 text-[14px] border border-zinc-200 dark:border-zinc-700 rounded-md outline-none focus:border-brand-500 shadow-none bg-white dark:bg-zinc-900 text-zinc-900 dark:text-white placeholder:text-zinc-500 dark:placeholder:text-zinc-400"
                                    />
                                </div>
                            </div>

                            {/* Options list */}
                            <div className="overflow-y-auto max-h-60">
                                {filteredOptions.length > 0 ? (
                                    filteredOptions.map((option) => (
                                        <button
                                            key={option.value}
                                            type="button"
                                            onClick={() => handleSelect(option)}
                                            className={`
                                                w-full px-4 py-2.5 text-left text-[14px] transition-colors
                                                hover:bg-zinc-100 dark:hover:bg-zinc-700 cursor-pointer
                                                ${selectedOption?.value === option.value ? 'bg-brand-500/10 text-brand-600 font-medium' : 'text-zinc-900 dark:text-white'}
                                            `}
                                        >
                                            {option.label}
                                        </button>
                                    ))
                                ) : (
                                    <div className="px-4 py-8 text-center text-zinc-500 dark:text-zinc-400 text-[14px]">
                                        Nenhum resultado encontrado
                                    </div>
                                )}
                            </div>
                        </div>
                    )}
                </div>

                {helperText && !error && (
                    <p className="mt-1.5 text-[12px] text-zinc-600 dark:text-zinc-400">{helperText}</p>
                )}
                {error && (
                    <p className="mt-1 text-[13px] text-red-500 flex items-center gap-1">
                        <i className="ri-error-warning-line" />
                        {error}
                    </p>
                )}
            </div>
        );
    }
);

SearchableSelect.displayName = "SearchableSelect";

export default SearchableSelect;
