'use client';
import { useEffect, useMemo, useRef, useState, } from 'react';
import { FaSortDown } from 'react-icons/fa';
import { Input } from '../../01-atoms';
import { debounce } from '../../../utils';
/**
 * Autocomplete component that provides a filterable dropdown list of options.
 *
 * @component
 * @example
 * // Example usage of Autocomplete component
 * <Autocomplete
 *   label="Search"
 *   options={[{ label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }]}
 *   onSelect={(option) => console.log('Selected:', option)}
 *   onChange={(query) => console.log('Query:', query)}
 * />
 *
 * @param {Object} props - The properties of the Autocomplete component.
 * @param {OptionType[]} props.options - The list of available options to display.
 * @param {Function} [props.onSelect] - Callback fired when an option is selected.
 * @param {Function} [props.onChange] - Callback fired when the input query changes.
 * @param {Function} [props.onDebouncedChange] - Callback fired after the user stops typing, debounced by the specified delay.
 * @param {number} [props.debounceDelay=300] - Delay in milliseconds for the debounced callback.
 * @param {Function} [props.onHandleKeyDown] - Callback fired when the Enter key is pressed.
 * @param {boolean} [props.disabled] - Whether the input is disabled.
 * @param {string} props.label - The label text for the input field.
 * @param {string} [props.helperText] - Helper text displayed below the input.
 * @param {string} [props.error] - Error message displayed below the input.
 * @param {string} [props.value=''] - The controlled value of the input.
 *
 * @returns {ReactNode} The rendered Autocomplete component.
 */
export function Autocomplete({ options, onSelect, onChange, onDebouncedChange, debounceDelay = 200, onHandleKeyDown, disabled, label, helperText, error, value = '', }) {
    const [query, setQuery] = useState(value);
    const [filteredOptions, setFilteredOptions] = useState(options);
    const [isOpen, setIsOpen] = useState(false);
    const containerRef = useRef(null);
    const justSelectedRef = useRef(false);
    const onDebouncedChangeRef = useRef(onDebouncedChange);
    onDebouncedChangeRef.current = onDebouncedChange;
    const debouncedCallback = useMemo(() => debounce(async (q) => {
        const result = await onDebouncedChangeRef.current?.(q);
        if (Array.isArray(result)) {
            setFilteredOptions(result);
        }
    }, debounceDelay), [debounceDelay]);
    const handleChange = (e) => {
        const newQuery = e.target.value;
        setQuery(newQuery);
        setFilteredOptions(options.filter((option) => option.label.toLowerCase().includes(newQuery.toLowerCase())));
        onChange?.(newQuery);
        debouncedCallback(newQuery);
    };
    const handleOptionClick = (option) => {
        justSelectedRef.current = true;
        setQuery(option.label);
        setFilteredOptions([]);
        setIsOpen(false);
        onSelect?.(option);
    };
    const handleFocus = () => {
        setIsOpen(true);
        setFilteredOptions(options.filter((option) => option.label.toLowerCase().includes(query.toLowerCase())));
    };
    const handleBlur = () => {
        setTimeout(() => {
            setIsOpen(false);
        }, 200);
    };
    const handleIcon = () => (<FaSortDown className="absolute -top-1 right-2" onClick={() => setIsOpen(!isOpen)}/>);
    const handleKeyDown = (e) => {
        if (e.key === 'Enter' && onHandleKeyDown) {
            onHandleKeyDown();
        }
    };
    useEffect(() => {
        if (justSelectedRef.current) {
            justSelectedRef.current = false;
            return;
        }
        if (!value) {
            setQuery('');
            setFilteredOptions([]);
            setIsOpen(false);
            return;
        }
        const matchedOption = options.find((opt) => String(opt.value) === value);
        setQuery(matchedOption ? matchedOption.label : value);
    }, [value]);
    useEffect(() => {
        setFilteredOptions(options);
    }, [options]);
    return (<div className="relative w-full" ref={containerRef}>
      <Input label={label} input={{
            type: 'text',
            value: query,
            onChange: handleChange,
            onFocus: handleFocus,
            onBlur: handleBlur,
            onKeyDown: handleKeyDown,
            disabled,
        }} iconR={handleIcon()} helperText={helperText} error={error}/>
      {!!isOpen && (<ul className="absolute z-40 flex max-h-28 w-full flex-col gap-y-4 overflow-y-auto rounded-md bg-white px-3 py-2 shadow-lg">
          {filteredOptions?.length > 0 ? (filteredOptions.map((option) => (<button key={option.value} onClick={() => handleOptionClick(option)} className="cursor-pointer py-0.5 text-left">
                {option.label}
              </button>))) : (<li className="autocomplete-option no-options">No hay opciones</li>)}
        </ul>)}
    </div>);
}
//# sourceMappingURL=Autocomplete.jsx.map