import { ChevronsUpDown, Loader2, X } from 'lucide-react';
import { useEffect, useId, useState } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { cn } from '@/lib/utils';

export type ClientSearchRow = {
    id: number;
    name: string;
    cif: string;
    vat_number: string;
};

async function fetchClients(params: {
    q?: string;
    id?: number;
    cif?: string;
    signal?: AbortSignal;
}): Promise<ClientSearchRow[]> {
    const searchParams = new URLSearchParams();
    if (params.id !== undefined) {
        searchParams.set('id', String(params.id));
    } else if (params.cif) {
        searchParams.set('cif', params.cif);
    } else if (params.q) {
        searchParams.set('q', params.q);
    }

    const response = await fetch(`/admin/clients/search?${searchParams.toString()}`, {
        headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
        credentials: 'same-origin',
        signal: params.signal,
    });

    if (!response.ok) throw new Error('Client search failed');

    const payload = (await response.json()) as { data: ClientSearchRow[] };
    return Array.isArray(payload.data) ? payload.data : [];
}

type ClientAsyncSelectProps = {
    /** CIF-ul clientului curent — folosit pentru pre-selectare automată la mount */
    initialCif?: string | null;
    onSelect: (client: ClientSearchRow | null) => void;
    disabled?: boolean;
    className?: string;
};

export function ClientAsyncSelect({ initialCif, onSelect, disabled = false, className }: ClientAsyncSelectProps) {
    const listId = useId();
    const [open, setOpen] = useState(false);
    const [searchQuery, setSearchQuery] = useState('');
    const [results, setResults] = useState<ClientSearchRow[]>([]);
    const [searchLoading, setSearchLoading] = useState(false);
    const [resolved, setResolved] = useState<ClientSearchRow | null>(null);
    const [resolveLoading, setResolveLoading] = useState(false);

    // Resolve initial CIF to a client entity on mount / when CIF changes
    useEffect(() => {
        const cif = initialCif?.trim() ?? '';
        if (cif === '') {
            setResolved(null);
            return;
        }

        let cancelled = false;
        setResolveLoading(true);

        void (async () => {
            try {
                const rows = await fetchClients({ cif });
                if (!cancelled) setResolved(rows[0] ?? null);
            } catch {
                if (!cancelled) setResolved(null);
            } finally {
                if (!cancelled) setResolveLoading(false);
            }
        })();

        return () => { cancelled = true; };
    }, [initialCif]);

    useEffect(() => {
        if (!open) return;

        const q = searchQuery.trim();
        if (q.length < 2) {
            setResults([]);
            setSearchLoading(false);
            return;
        }

        const controller = new AbortController();
        setSearchLoading(true);

        const timer = window.setTimeout(() => {
            void (async () => {
                try {
                    const rows = await fetchClients({ q, signal: controller.signal });
                    if (!controller.signal.aborted) setResults(rows);
                } catch (error) {
                    if (error instanceof DOMException && error.name === 'AbortError') return;
                    if (!controller.signal.aborted) setResults([]);
                } finally {
                    if (!controller.signal.aborted) setSearchLoading(false);
                }
            })();
        }, 280);

        return () => {
            window.clearTimeout(timer);
            controller.abort();
            setSearchLoading(false);
        };
    }, [open, searchQuery]);

    const label = resolveLoading ? '...' : (resolved?.name ?? null);

    return (
        <Popover
            open={open}
            onOpenChange={(next) => {
                setOpen(next);
                if (!next) { setSearchQuery(''); setResults([]); }
            }}
        >
            <PopoverTrigger asChild>
                <Button
                    type="button"
                    variant="outline"
                    role="combobox"
                    aria-expanded={open}
                    aria-controls={listId}
                    disabled={disabled}
                    className={cn(
                        'h-9 w-full justify-between gap-1 px-2 font-normal',
                        !label && 'text-muted-foreground',
                        className,
                    )}
                >
                    <span className="min-w-0 flex-1 truncate text-left text-sm">
                        {resolveLoading
                            ? <Loader2 className="h-4 w-4 animate-spin opacity-60" aria-hidden />
                            : (label ?? 'Selectează client...')}
                    </span>
                    {resolved !== null ? (
                        <X
                            className="h-3.5 w-3.5 shrink-0 opacity-50 hover:opacity-100"
                            aria-hidden
                            onClick={(e) => {
                                e.stopPropagation();
                                setResolved(null);
                                onSelect(null);
                            }}
                        />
                    ) : (
                        <ChevronsUpDown className="h-4 w-4 shrink-0 opacity-50" aria-hidden />
                    )}
                </Button>
            </PopoverTrigger>
            <PopoverContent align="start" className="w-96 p-2">
                <div className="flex flex-col gap-2">
                    <Input
                        autoFocus
                        autoComplete="off"
                        placeholder="Caută după nume sau CIF (min. 2 caractere)"
                        value={searchQuery}
                        onChange={(e) => setSearchQuery(e.target.value)}
                        disabled={disabled}
                    />
                    <div
                        id={listId}
                        role="listbox"
                        className="max-h-60 overflow-y-auto rounded-md border border-border/60 bg-background"
                    >
                        {searchLoading ? (
                            <div className="flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground">
                                <Loader2 className="h-4 w-4 animate-spin" aria-hidden />
                                Se încarcă...
                            </div>
                        ) : searchQuery.trim().length > 0 && searchQuery.trim().length < 2 ? (
                            <p className="px-2 py-4 text-center text-xs text-muted-foreground">
                                Introduceți cel puțin 2 caractere.
                            </p>
                        ) : results.length === 0 ? (
                            <p className="px-2 py-4 text-center text-xs text-muted-foreground">
                                {searchQuery.trim().length >= 2 ? 'Niciun client găsit.' : 'Scrieți pentru a căuta clienți.'}
                            </p>
                        ) : (
                            <ul className="divide-y divide-dashed divide-border/60 p-1">
                                {results.map((row) => (
                                    <li key={row.id}>
                                        <button
                                            type="button"
                                            role="option"
                                            aria-selected={row.id === resolved?.id}
                                            className={cn(
                                                'w-full cursor-pointer rounded-sm px-2 py-1.5 text-left text-sm hover:bg-muted',
                                                row.id === resolved?.id && 'bg-muted/80',
                                            )}
                                            onClick={() => {
                                                setResolved(row);
                                                onSelect(row);
                                                setOpen(false);
                                                setSearchQuery('');
                                            }}
                                        >
                                            <span className="block font-medium">{row.name}</span>
                                            <span className="mt-0.5 block text-xs text-muted-foreground">
                                                CIF: {row.cif || '—'}
                                            </span>
                                        </button>
                                    </li>
                                ))}
                            </ul>
                        )}
                    </div>
                </div>
            </PopoverContent>
        </Popover>
    );
}
