import { Check, ChevronsUpDown, X } from 'lucide-react';
import { useMemo } from 'react';
import {
    Command,
    CommandEmpty,
    CommandGroup,
    CommandInput,
    CommandItem,
    CommandList,
} from '@/components/ui/command';
import {
    Popover,
    PopoverContent,
    PopoverTrigger,
} from '@/components/ui/popover';
import { brandLabel } from '@/lib/catalog';
import { cn } from '@/lib/utils';
import type { CatalogModelOption } from '@/types/catalog';

interface ModelMultiSelectProps {
    models: CatalogModelOption[];
    selected: number[];
    brand?: string | null;
    onChange: (modelIds: number[]) => void;
    className?: string;
}

function modelLabel(model: CatalogModelOption): string {
    return `${model.name} (${model.year})`;
}

/*
 * Multi-select model filter (shadcn Combobox: Popover + Command). Options are
 * per pdb_models row, so the same model_key can appear once per model year —
 * the year is part of every label and of the search value.
 */
export function ModelMultiSelect({
    models,
    selected,
    brand = null,
    onChange,
    className,
}: ModelMultiSelectProps) {
    const options = useMemo(
        () =>
            brand === null
                ? models
                : models.filter((model) => model.brand_code === brand),
        [models, brand],
    );

    const selectedSet = useMemo(() => new Set(selected), [selected]);

    const groups = useMemo(() => {
        const byBrand = new Map<string, CatalogModelOption[]>();

        for (const model of options) {
            const key = model.brand_code ?? '';

            const group = byBrand.get(key) ?? [];
            group.push(model);
            byBrand.set(key, group);
        }

        return [...byBrand.entries()];
    }, [options]);

    const toggle = (modelId: number) => {
        const next = new Set(selectedSet);

        if (next.has(modelId)) {
            next.delete(modelId);
        } else {
            next.add(modelId);
        }

        onChange([...next].sort((a, b) => a - b));
    };

    const label =
        selected.length === 0
            ? 'All models'
            : selected.length === 1
              ? modelLabel(
                    options.find((model) => model.id === selected[0]) ??
                        models.find((model) => model.id === selected[0]) ?? {
                            id: selected[0],
                            brand_code: null,
                            model_key: '',
                            year: '',
                            name: `#${selected[0]}`,
                        },
                )
              : `${selected.length} models`;

    return (
        <Popover>
            <PopoverTrigger asChild>
                <button
                    type="button"
                    role="combobox"
                    aria-label="Filter by model"
                    className={cn(
                        'inline-flex h-9 w-64 cursor-pointer items-center justify-between gap-2 rounded-md border border-gray-200 bg-white px-3 text-xs font-semibold text-astara-purple transition-colors hover:bg-gray-50 focus-visible:ring-2 focus-visible:ring-astara-orange/40 focus-visible:outline-none',
                        className,
                    )}
                >
                    <span className="truncate">{label}</span>
                    <span className="flex shrink-0 items-center gap-1">
                        {selected.length > 0 && (
                            <span
                                role="button"
                                tabIndex={0}
                                aria-label="Clear model filter"
                                className="rounded p-0.5 text-gray-400 hover:bg-gray-100 hover:text-astara-purple"
                                onClick={(event) => {
                                    event.stopPropagation();
                                    onChange([]);
                                }}
                                onKeyDown={(event) => {
                                    if (
                                        event.key === 'Enter' ||
                                        event.key === ' '
                                    ) {
                                        event.stopPropagation();
                                        onChange([]);
                                    }
                                }}
                            >
                                <X size={12} />
                            </span>
                        )}
                        <ChevronsUpDown size={14} className="text-gray-400" />
                    </span>
                </button>
            </PopoverTrigger>
            <PopoverContent align="start" className="w-80 p-0">
                <Command>
                    <CommandInput placeholder="Search model, year or brand..." />
                    <CommandList>
                        <CommandEmpty>No models found.</CommandEmpty>
                        {groups.map(([brandCode, brandModels]) => (
                            <CommandGroup
                                key={brandCode}
                                heading={brandLabel(brandCode)}
                            >
                                {brandModels.map((model) => {
                                    const isSelected = selectedSet.has(
                                        model.id,
                                    );

                                    return (
                                        <CommandItem
                                            key={model.id}
                                            value={`${brandCode} ${model.name} ${model.model_key} ${model.year}`}
                                            onSelect={() => toggle(model.id)}
                                            className="text-xs"
                                        >
                                            <span
                                                className={cn(
                                                    'flex size-4 shrink-0 items-center justify-center rounded-[4px] border',
                                                    isSelected
                                                        ? 'border-astara-purple bg-astara-purple text-white'
                                                        : 'border-gray-300 bg-white',
                                                )}
                                            >
                                                {isSelected && (
                                                    <Check
                                                        size={11}
                                                        strokeWidth={3}
                                                    />
                                                )}
                                            </span>
                                            <span className="flex min-w-0 flex-col">
                                                <span className="truncate font-bold text-astara-purple">
                                                    {modelLabel(model)}
                                                </span>
                                                <span className="truncate text-[10px] text-gray-400">
                                                    {model.model_key}
                                                </span>
                                            </span>
                                        </CommandItem>
                                    );
                                })}
                            </CommandGroup>
                        ))}
                    </CommandList>
                </Command>
                <div className="flex items-center justify-between border-t border-gray-100 px-3 py-2">
                    <button
                        type="button"
                        onClick={() => onChange([])}
                        disabled={selected.length === 0}
                        className="cursor-pointer text-[10px] font-bold tracking-widest text-gray-400 uppercase transition-colors hover:text-astara-purple disabled:cursor-not-allowed disabled:opacity-40"
                    >
                        Clear
                    </button>
                    <span className="text-[10px] font-bold tracking-widest text-gray-400 uppercase">
                        {selected.length} selected
                    </span>
                </div>
            </PopoverContent>
        </Popover>
    );
}
