import { cn } from '@/lib/utils';
import { Facets } from '@/types/models';
import { Command } from 'cmdk';
import { Check } from 'lucide-react';
import { Filters, FilterKind } from './filters';

type EditorProps = { filters: Filters; facets?: Facets; onChange: (f: Filters) => void };

function MultiSelect({ items, selected, onToggle, placeholder }: { items: { name: string; slug: string }[]; selected: string[]; onToggle: (slug: string) => void; placeholder: string }) {
    return (
        <Command label={placeholder} className="w-64">
            <Command.Input autoFocus placeholder={placeholder} className="h-10 w-full border-b border-border bg-transparent px-3 text-sm outline-none placeholder:text-muted-foreground/70" />
            <Command.List className="max-h-64 overflow-y-auto p-1">
                <Command.Empty className="px-3 py-6 text-center text-sm text-muted-foreground">No matches.</Command.Empty>
                {items.map((i) => {
                    const on = selected.includes(i.slug);
                    return (
                        <Command.Item key={i.slug} value={i.name} onSelect={() => onToggle(i.slug)} className="flex cursor-pointer items-center gap-2.5 rounded-md px-2.5 py-1.5 text-sm aria-selected:bg-accent">
                            <span className={cn('flex size-4 items-center justify-center rounded border border-input transition', on && 'border-primary bg-primary text-primary-foreground')}>{on && <Check className="size-3" strokeWidth={3} />}</span>
                            {i.name}
                        </Command.Item>
                    );
                })}
            </Command.List>
        </Command>
    );
}

const selectCls = 'h-9 w-full rounded-lg border border-input bg-card/60 px-2.5 text-sm outline-none focus:border-ring focus:ring-4 focus:ring-ring/15';
const YEARS = Array.from({ length: 30 }, (_, i) => String(new Date().getFullYear() + 1 - i));
const Preset = ({ label, onClick, active }: { label: string; onClick: () => void; active?: boolean }) => (
    <button type="button" onClick={onClick} className={cn('rounded-full border px-2.5 py-1 text-xs transition', active ? 'border-primary bg-primary/15 text-foreground' : 'border-border text-muted-foreground hover:text-foreground')}>{label}</button>
);

function YearEditor({ filters, onChange }: EditorProps) {
    const y = new Date().getFullYear();
    const set = (from?: string, to?: string) => onChange({ ...filters, year_from: from, year_to: to });
    return (
        <div className="w-64 space-y-3 p-3">
            <div className="grid grid-cols-2 gap-2">
                <label className="space-y-1 text-caption">From
                    <select className={selectCls} value={filters.year_from ?? ''} onChange={(e) => set(e.target.value || undefined, filters.year_to)}><option value="">Any</option>{YEARS.map((v) => <option key={v}>{v}</option>)}</select>
                </label>
                <label className="space-y-1 text-caption">To
                    <select className={selectCls} value={filters.year_to ?? ''} onChange={(e) => set(filters.year_from, e.target.value || undefined)}><option value="">Any</option>{YEARS.map((v) => <option key={v}>{v}</option>)}</select>
                </label>
            </div>
            <div className="flex flex-wrap gap-1.5">
                <Preset label="Last 2 years" onClick={() => set(String(y - 1), undefined)} />
                <Preset label="2020s" onClick={() => set('2020', '2029')} />
                <Preset label="2010s" onClick={() => set('2010', '2019')} />
            </div>
        </div>
    );
}

const SCORES = Array.from({ length: 11 }, (_, i) => String(i));

function RatingEditor({ filters, onChange }: EditorProps) {
    const set = (min?: string, max?: string) => onChange({ ...filters, rating_min: min, rating_max: max });
    return (
        <div className="w-64 space-y-3 p-3">
            <div className="grid grid-cols-2 gap-2">
                <label className="space-y-1 text-caption">Min
                    <select className={selectCls} value={filters.rating_min ?? '0'} onChange={(e) => set(e.target.value === '0' ? undefined : e.target.value, filters.rating_max)}>{SCORES.map((v) => <option key={v}>{v}</option>)}</select>
                </label>
                <label className="space-y-1 text-caption">Max
                    <select className={selectCls} value={filters.rating_max ?? '10'} onChange={(e) => set(filters.rating_min, e.target.value === '10' ? undefined : e.target.value)}>{SCORES.map((v) => <option key={v}>{v}</option>)}</select>
                </label>
            </div>
            <div className="flex flex-wrap gap-1.5">
                {['6', '7', '8', '9'].map((v) => <Preset key={v} label={`${v}+`} active={filters.rating_min === v && !filters.rating_max} onClick={() => set(v, undefined)} />)}
            </div>
        </div>
    );
}

export default function FilterEditor({ kind, filters, facets, onChange }: EditorProps & { kind: FilterKind }) {
    const toggle = (key: 'genre' | 'platform' | 'tag') => (slug: string) => {
        const cur = filters[key] ?? [];
        onChange({ ...filters, [key]: cur.includes(slug) ? cur.filter((s) => s !== slug) : [...cur, slug] });
    };
    switch (kind) {
        case 'genre': return <MultiSelect items={facets?.genres ?? []} selected={filters.genre ?? []} onToggle={toggle('genre')} placeholder="Filter genres…" />;
        case 'platform': return <MultiSelect items={facets?.platforms ?? []} selected={filters.platform ?? []} onToggle={toggle('platform')} placeholder="Filter platforms…" />;
        case 'tag': return <MultiSelect items={facets?.tags ?? []} selected={filters.tag ?? []} onToggle={toggle('tag')} placeholder="Filter tags…" />;
        case 'year': return <YearEditor filters={filters} onChange={onChange} />;
        case 'rating': return <RatingEditor filters={filters} onChange={onChange} />;
    }
}
