import { Button } from '@/components/ui/button';
import { useTranslation } from '@/hooks/use-translation';
import { cn } from '@/lib/utils';
import { Check, ChevronsUpDown, Search, UserPlus, X } from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';
import type { OwnerOption } from '../types';
import { StandaloneCreateOwnerDialog } from './StandaloneCreateOwnerDialog';

/**
 * Inline searchable combobox for existing propriétaires.
 *
 * Rendered as a plain absolutely-positioned dropdown (NOT a Radix Popover) so
 * it stays inside the AddFolderDialog's DOM tree. Using Popover here portals
 * the content to document.body, which the parent Dialog's FocusScope then
 * treats as "outside" — it refocuses the dialog on every keystroke and the
 * search input never keeps focus long enough to type. Staying inline avoids
 * the whole fight.
 *
 * "+ Ajouter un nouveau propriétaire" is pinned at the bottom of the dropdown.
 */
export const OwnerCombobox = ({
    value,
    owners,
    onSelect,
    onClear,
    onOwnerCreated,
    phonesPrefix,
}: {
    value: OwnerOption | null;
    owners: OwnerOption[];
    onSelect: (owner: OwnerOption) => void;
    onClear: () => void;
    onOwnerCreated: (owner: OwnerOption) => void;
    phonesPrefix: string[];
}) => {
    const { t } = useTranslation();
    const [open, setOpen] = useState(false);
    const [createOpen, setCreateOpen] = useState(false);
    const [query, setQuery] = useState('');
    const inputRef = useRef<HTMLInputElement>(null);
    const containerRef = useRef<HTMLDivElement>(null);

    // Auto-focus the search input when the dropdown opens.
    // Production build (Vite + Terser) can eliminate a bare setTimeout focus if it
    // thinks the effect has no side-effects visible to React. requestAnimationFrame
    // + a defensive guard is survive-bundler-safe: the RAF callback always runs
    // after paint, the ref is guaranteed to be attached because the input is
    // conditionally rendered only while `open === true`, and the `autoFocus`
    // attribute on the input itself is a belt-and-braces fallback.
    useEffect(() => {
        if (!open) {
            setQuery('');
            return;
        }
        const raf = requestAnimationFrame(() => {
            inputRef.current?.focus();
        });
        return () => cancelAnimationFrame(raf);
    }, [open]);

    // Close the dropdown on outside click.
    useEffect(() => {
        if (!open) return;
        const onDocDown = (e: MouseEvent) => {
            if (!containerRef.current) return;
            if (!containerRef.current.contains(e.target as Node)) setOpen(false);
        };
        document.addEventListener('mousedown', onDocDown);
        return () => document.removeEventListener('mousedown', onDocDown);
    }, [open]);

    // Close on Escape.
    useEffect(() => {
        if (!open) return;
        const onKey = (e: KeyboardEvent) => {
            if (e.key === 'Escape') setOpen(false);
        };
        document.addEventListener('keydown', onKey);
        return () => document.removeEventListener('keydown', onKey);
    }, [open]);

    const filteredOwners = useMemo(() => {
        const q = query.trim().toLowerCase();
        if (!q) return owners;
        return owners.filter((o) => {
            const haystack = `${o.name} ${o.last_name ?? ''} ${o.email} ${o.phone ?? ''}`.toLowerCase();
            return haystack.includes(q);
        });
    }, [owners, query]);

    const handleCreateNew = () => {
        setOpen(false);
        setTimeout(() => setCreateOpen(true), 50);
    };

    const handleCreated = (owner: OwnerOption) => {
        onOwnerCreated(owner);
        onSelect(owner);
    };

    return (
        <>
            <div className="flex items-center gap-2">
                <div ref={containerRef} className="relative w-full">
                    <Button
                        type="button"
                        variant="outline"
                        role="combobox"
                        aria-expanded={open}
                        aria-haspopup="listbox"
                        onClick={() => setOpen((v) => !v)}
                        className="w-full justify-between"
                    >
                        {value ? (
                            <span className="truncate">
                                {value.name} {value.last_name ?? ''}
                                <span className="text-muted-foreground ml-2 text-xs">({value.email})</span>
                            </span>
                        ) : (
                            <span className="text-muted-foreground">{t('crm', 'owner_combobox_placeholder')}</span>
                        )}
                        <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>

                    {open && (
                        <div
                            role="listbox"
                            className="bg-popover absolute top-full left-0 z-[100] mt-1 flex w-full flex-col overflow-hidden rounded-md border shadow-md"
                        >
                            <div className="flex items-center gap-2 border-b px-3 py-2">
                                <Search className="text-muted-foreground h-4 w-4 shrink-0" />
                                <input
                                    ref={inputRef}
                                    type="text"
                                    value={query}
                                    onChange={(e) => setQuery(e.target.value)}
                                    placeholder={t('crm', 'owner_combobox_search_placeholder')}
                                    className="placeholder:text-muted-foreground h-8 flex-1 bg-transparent text-sm outline-none"
                                    autoComplete="off"
                                    autoFocus
                                />
                            </div>
                            <div className="max-h-[240px] overflow-y-auto p-1">
                                {filteredOwners.length === 0 ? (
                                    <div className="text-muted-foreground px-2 py-6 text-center text-sm">
                                        {t('crm', 'owner_combobox_empty')}
                                    </div>
                                ) : (
                                    filteredOwners.map((owner) => {
                                        const isSelected = value?.id === owner.id;
                                        return (
                                            <button
                                                key={owner.id}
                                                type="button"
                                                onClick={() => {
                                                    onSelect(owner);
                                                    setOpen(false);
                                                }}
                                                className={cn(
                                                    'flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm transition-colors',
                                                    'hover:bg-accent hover:text-accent-foreground',
                                                    isSelected && 'bg-accent/50',
                                                )}
                                            >
                                                <div className="flex flex-col">
                                                    <span className="font-medium">
                                                        {owner.name} {owner.last_name ?? ''}
                                                    </span>
                                                    <span className="text-muted-foreground text-xs">{owner.email}</span>
                                                </div>
                                                <Check
                                                    className={cn(
                                                        'ml-auto h-4 w-4',
                                                        isSelected ? 'opacity-100' : 'opacity-0',
                                                    )}
                                                />
                                            </button>
                                        );
                                    })
                                )}
                            </div>
                            <div className="bg-popover border-t p-1">
                                <button
                                    type="button"
                                    onClick={handleCreateNew}
                                    className="text-secondary hover:bg-secondary/10 flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-2 text-sm font-medium transition-colors"
                                >
                                    <UserPlus className="h-4 w-4" />
                                    {t('crm', 'owner_combobox_create_new')}
                                </button>
                            </div>
                        </div>
                    )}
                </div>
                {value && (
                    <Button
                        type="button"
                        variant="ghost"
                        size="icon"
                        onClick={onClear}
                        aria-label={t('crm', 'owner_combobox_clear')}
                        title={t('crm', 'owner_combobox_clear')}
                    >
                        <X className="h-4 w-4" />
                    </Button>
                )}
            </div>

            <StandaloneCreateOwnerDialog
                open={createOpen}
                onOpenChange={setCreateOpen}
                onCreated={handleCreated}
                phonesPrefix={phonesPrefix}
            />
        </>
    );
};
