import React, { useState, useEffect, useMemo } from 'react';
import { Typeahead } from 'react-bootstrap-typeahead';
import { Eraser } from 'lucide-react';
import styles from './TypeaheadClienteConLimpiar.module.css';

export interface TypeaheadClienteConLimpiarProps<T extends object> {
    id: string;
    labelKey: string;
    placeholder: string;
    selected: T[];
    options: T[];
    isLoading?: boolean;
    isInvalid: boolean;
    errorId: string;
    onChange: (selected: T[]) => void;
    onLimpiar: () => void;
    mostrarBotonLimpiar: boolean;
    ariaLabelLimpiar?: string;
    positionFixed?: boolean;
    dropup?: boolean;
}

export function TypeaheadClienteConLimpiar<T extends object>({
    id,
    labelKey,
    placeholder,
    selected,
    options,
    isLoading = false,
    isInvalid,
    errorId,
    onChange,
    onLimpiar,
    mostrarBotonLimpiar,
    ariaLabelLimpiar = 'Limpiar selección',
    positionFixed = false,
    dropup = false,
}: TypeaheadClienteConLimpiarProps<T>) {
    const [searchTerm, setSearchTerm] = useState('');
    const [debouncedTerm, setDebouncedTerm] = useState('');

    useEffect(() => {
        const timer = setTimeout(() => setDebouncedTerm(searchTerm), 300);
        return () => clearTimeout(timer);
    }, [searchTerm]);

    // Limpiar los términos de búsqueda si ya hay un cliente seleccionado.
    // Esto previene que una selección desde otro Typeahead dispare una búsqueda.
    useEffect(() => {
        if (selected && selected.length > 0) {
            setSearchTerm('');
            setDebouncedTerm('');
        }
    }, [selected]);

    const filteredOptions = useMemo(() => {
        // Si hay una selección activa, no mostramos opciones.
        if (selected && selected.length > 0) return [];
        if (!options || options.length === 0) return [];
        if (!debouncedTerm) return options.slice(0, 100);
        
        const lower = debouncedTerm.toLowerCase();
        return options.filter((opt: any) => {
            const val = opt[labelKey];
            return val && String(val).toLowerCase().includes(lower);
        }).slice(0, 100);
    }, [debouncedTerm, options, labelKey, selected]);

    return (
        <div className={styles.grupoTypeaheadConLimpiar}>
            <Typeahead
                id={id}
                labelKey={labelKey}
                selected={selected}
                onChange={onChange}
                onInputChange={(text, e) => {
                    // Evitar actualizar el estado de búsqueda por cambios programáticos 
                    // (como cuando se sincroniza con otro Typeahead)
                    if (e) {
                        setSearchTerm(text);
                    }
                }}
                options={filteredOptions}
                filterBy={() => true}
                placeholder={placeholder}
                isLoading={isLoading}
                minLength={1}
                isInvalid={isInvalid}
                positionFixed={positionFixed}
                dropup={dropup}
                flip={!dropup}
                inputProps={{
                    className: `form-control-sm ${isInvalid ? 'is-invalid' : ''}`,
                    'aria-invalid': isInvalid,
                    'aria-describedby': isInvalid ? errorId : undefined,
                }}
            />
            {mostrarBotonLimpiar ? (
                <button
                    type="button"
                    className={styles.botonLimpiarTypeahead}
                    onClick={onLimpiar}
                    onMouseDown={(event) => event.preventDefault()}
                    title={ariaLabelLimpiar}
                    aria-label={ariaLabelLimpiar}
                >
                    <Eraser size={14} aria-hidden />
                </button>
            ) : null}
        </div>
    );
}
