import { useEffect, useId, useRef, useState } from 'react';
import { ChevronDown, X } from 'lucide-react';
import { CheckBox } from '@/Components/Proto/UI/CheckBox';
import { cn } from '@/lib/utils';

/**
 * MultiSelect — Proto-styled multi-select over a bordered floating-label trigger.
 * Self-contained (no shadcn Popover in this project); a simple absolutely-positioned
 * panel with an outside-click / Esc handler. Options render as real <label>+CheckBox
 * rows so the control is keyboard/AT accessible.
 *
 * Props:
 *   label       — floating chip label (also the panel's aria-label)
 *   options     — [{ ID, label }]
 *   value       — number[] of selected IDs
 *   onChange    — (number[]) => void  (always emits integers)
 *   placeholder — trigger text when nothing is selected
 *
 * Trigger skin matches FloatingField's outline select (border-input bg-card, h-11,
 * floated label chip) so it lines up in the same filter grid.
 */
export function MultiSelect({ label, options = [], value = [], onChange, placeholder = 'Select…' }) {
    const [open, setOpen] = useState(false);
    const rootRef = useRef(null);
    const panelId = useId();

    // Close on outside-click / Esc while open.
    useEffect(() => {
        if (!open) return;
        const onPointer = (e) => {
            if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(false);
        };
        const onKey = (e) => {
            if (e.key === 'Escape') setOpen(false);
        };
        document.addEventListener('mousedown', onPointer);
        document.addEventListener('keydown', onKey);
        return () => {
            document.removeEventListener('mousedown', onPointer);
            document.removeEventListener('keydown', onKey);
        };
    }, [open]);

    const selected = new Set(value.map(Number));

    const toggle = (id) => {
        const n = Number(id);
        const next = selected.has(n) ? value.filter((v) => Number(v) !== n) : [...value, n];
        onChange(next.map(Number));
    };

    const clear = (e) => {
        e.stopPropagation();
        onChange([]);
    };

    const selectedLabels = options.filter((o) => selected.has(Number(o.ID))).map((o) => o.label);
    const summary =
        selectedLabels.length === 0
            ? placeholder
            : selectedLabels.length <= 2
                ? selectedLabels.join(', ')
                : `${selectedLabels.length} selected`;

    return (
        <div ref={rootRef} className="relative block">
            <button
                type="button"
                aria-haspopup="listbox"
                aria-expanded={open}
                aria-controls={open ? panelId : undefined}
                onClick={() => setOpen((o) => !o)}
                className="relative flex h-11 w-full items-center gap-2 rounded-lg border border-input bg-card pl-3 pr-3 text-left text-[12px] text-foreground outline-none transition-colors hover:border-primary focus-visible:border-primary focus-visible:ring-1 focus-visible:ring-primary"
            >
                <span className={cn('block min-w-0 flex-1 truncate', selectedLabels.length === 0 && 'text-muted-foreground')}>
                    {summary}
                </span>
                {selectedLabels.length > 0 && (
                    <span className="inline-grid size-4.5 shrink-0 place-items-center rounded-full bg-primary/10 text-[10px] font-bold tabular-nums text-primary">
                        {selectedLabels.length}
                    </span>
                )}
                {selectedLabels.length > 0 && (
                    <span
                        role="button"
                        tabIndex={-1}
                        aria-label={`Clear ${label}`}
                        onClick={clear}
                        className="grid size-5 shrink-0 place-items-center rounded-md text-muted-foreground transition-colors hover:bg-secondary hover:text-foreground"
                    >
                        <X className="size-3.5" />
                    </span>
                )}
                <ChevronDown aria-hidden="true" className={cn('size-3.5 shrink-0 text-muted-foreground transition-transform', open && 'rotate-180')} />
            </button>

            <span className="pointer-events-none absolute left-1.5 top-0 z-[1] -translate-y-1/2 bg-card px-1 text-[9px] font-semibold text-muted-foreground">
                {label}
            </span>

            {open && (
                <div
                    id={panelId}
                    role="listbox"
                    aria-multiselectable="true"
                    aria-label={label}
                    className="absolute left-0 top-full z-50 mt-1.5 max-h-64 w-full min-w-56 overflow-auto rounded-lg border border-border bg-card p-1 shadow-lg"
                >
                    <div className="flex items-center justify-between px-2 py-1">
                        <span className="text-[10px] font-semibold uppercase tracking-wide text-muted-foreground">{label}</span>
                        {selectedLabels.length > 0 && (
                            <button
                                type="button"
                                onClick={() => onChange([])}
                                className="text-[10.5px] font-bold text-primary transition-colors hover:underline"
                            >
                                Clear
                            </button>
                        )}
                    </div>
                    {options.length === 0 ? (
                        <div className="px-2.5 py-2 text-[12px] text-muted-foreground">No options.</div>
                    ) : (
                        options.map((o) => {
                            const checked = selected.has(Number(o.ID));
                            return (
                                <label
                                    key={o.ID}
                                    className="flex cursor-pointer items-center gap-2.5 rounded-md px-2.5 py-1.5 text-[12px] text-foreground transition-colors hover:bg-secondary/60"
                                >
                                    <CheckBox size="sm" checked={checked} onChange={() => toggle(o.ID)} ariaLabel={o.label} />
                                    <span className="min-w-0 flex-1 truncate">{o.label}</span>
                                </label>
                            );
                        })
                    )}
                </div>
            )}
        </div>
    );
}
