import { cn } from '@/lib/utils';
import { Facets } from '@/types/models';
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/react';
import { AnimatePresence, motion } from 'framer-motion';
import { ChevronLeft, ChevronRight, Gamepad2, Layers, ListFilter, Star, Tag as TagIcon, X, CalendarRange } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import FilterEditor from './FilterEditors';
import { activeKinds, chipLabel, clearAll, clearKind, FilterKind, Filters, KIND_LABEL } from './filters';

const ICON = { genre: Layers, platform: Gamepad2, tag: TagIcon, year: CalendarRange, rating: Star } as const;
const ORDER: FilterKind[] = ['genre', 'platform', 'year', 'rating', 'tag'];
const panel = 'glass z-50 overflow-hidden rounded-xl border border-border shadow-lift outline-none [--anchor-gap:6px]';

function Chip({ kind, filters, facets, onChange }: { kind: FilterKind; filters: Filters; facets?: Facets; onChange: (f: Filters) => void }) {
    const Icon = ICON[kind];
    return (
        <motion.div layout initial={{ opacity: 0, scale: 0.92 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.92 }} transition={{ duration: 0.15 }} className="inline-flex h-8 items-center rounded-lg border border-border bg-card/70 text-sm shadow-soft">
            <Popover className="relative">
                <PopoverButton className="flex h-8 items-center gap-1.5 rounded-l-lg pl-2.5 pr-2 outline-none transition hover:bg-accent focus-visible:ring-2 focus-visible:ring-ring/60">
                    <Icon className="size-3.5 text-muted-foreground" />
                    <span className="max-w-[220px] truncate">{chipLabel(kind, filters, facets)}</span>
                </PopoverButton>
                <PopoverPanel anchor="bottom start" className={panel}>
                    <FilterEditor kind={kind} filters={filters} facets={facets} onChange={onChange} />
                </PopoverPanel>
            </Popover>
            <button onClick={() => onChange(clearKind(filters, kind))} aria-label={`Remove ${KIND_LABEL[kind]} filter`} className="flex h-8 items-center rounded-r-lg border-l border-border px-1.5 text-muted-foreground transition hover:bg-accent hover:text-foreground"><X className="size-3.5" /></button>
        </motion.div>
    );
}

function AddFilter({ filters, facets, onChange, hasActive }: { filters: Filters; facets?: Facets; onChange: (f: Filters) => void; hasActive: boolean }) {
    const [stage, setStage] = useState<FilterKind | null>(null);
    const btn = useRef<HTMLButtonElement>(null);

    useEffect(() => {
        const onKey = (e: KeyboardEvent) => {
            const t = e.target as HTMLElement;
            if (e.key === 'f' && !e.metaKey && !e.ctrlKey && !/input|textarea|select/i.test(t?.tagName ?? '') && !t?.isContentEditable) {
                e.preventDefault();
                btn.current?.click();
            }
        };
        window.addEventListener('keydown', onKey);
        return () => window.removeEventListener('keydown', onKey);
    }, []);

    return (
        <Popover className="relative">
            {({ open }) => (
                <>
                    <PopoverButton ref={btn} onClick={() => setStage(null)} className={cn('flex h-8 items-center gap-1.5 rounded-lg border border-dashed border-border px-2.5 text-sm text-muted-foreground outline-none transition hover:border-foreground/30 hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/60', open && 'border-solid bg-accent text-foreground')}>
                        <ListFilter className="size-3.5" />
                        {hasActive ? 'Add filter' : 'Filter'}
                        <kbd className="ml-1 hidden rounded border border-border px-1 text-[10px] sm:inline">F</kbd>
                    </PopoverButton>
                    <PopoverPanel anchor="bottom start" className={panel}>
                        {stage ? (
                            <div>
                                <button onClick={() => setStage(null)} className="flex w-full items-center gap-1.5 border-b border-border px-3 py-2 text-xs text-muted-foreground hover:text-foreground"><ChevronLeft className="size-3.5" />{KIND_LABEL[stage]}</button>
                                <FilterEditor kind={stage} filters={filters} facets={facets} onChange={onChange} />
                            </div>
                        ) : (
                            <div className="w-52 p-1">
                                {ORDER.map((k) => {
                                    const Icon = ICON[k];
                                    return (
                                        <button key={k} onClick={() => setStage(k)} className="flex w-full items-center gap-2.5 rounded-md px-2.5 py-2 text-sm hover:bg-accent">
                                            <Icon className="size-4 text-muted-foreground" />{KIND_LABEL[k]}
                                            {activeKinds(filters).includes(k) && <span className="ml-auto size-1.5 rounded-full bg-primary" />}
                                            {!activeKinds(filters).includes(k) && <ChevronRight className="ml-auto size-3.5 text-muted-foreground" />}
                                        </button>
                                    );
                                })}
                            </div>
                        )}
                    </PopoverPanel>
                </>
            )}
        </Popover>
    );
}

export default function FilterBar({ filters, facets, onChange }: { filters: Filters; facets?: Facets; onChange: (f: Filters) => void }) {
    const kinds = activeKinds(filters);
    return (
        <div className="flex flex-wrap items-center gap-2" role="toolbar" aria-label="Filters">
            <AnimatePresence initial={false} mode="popLayout">
                {kinds.map((k) => <Chip key={k} kind={k} filters={filters} facets={facets} onChange={onChange} />)}
            </AnimatePresence>
            <AddFilter filters={filters} facets={facets} onChange={onChange} hasActive={kinds.length > 0} />
            {kinds.length > 0 && <button onClick={() => onChange(clearAll(filters))} className="px-1.5 text-sm text-muted-foreground underline-offset-4 hover:text-foreground hover:underline">Clear all</button>}
        </div>
    );
}
