import * as React from 'react';
import { X } from 'lucide-react';
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';

type UserOption = { id: number | string; name: string };

type UserMultiSelectProps = {
    options: UserOption[];
    selected: string[];
    onChange: (selected: string[]) => void;
    placeholder?: string;
};

const BADGE_COLORS = [
    'bg-blue-100 text-blue-800',
    'bg-green-100 text-green-800',
    'bg-yellow-100 text-yellow-800',
    'bg-red-100 text-red-800',
    'bg-purple-100 text-purple-800',
];

export function UserMultiSelect({ options, selected, onChange, placeholder = 'Select...' }: UserMultiSelectProps) {
    const inputRef = React.useRef<HTMLInputElement>(null);
    const [open, setOpen] = React.useState(false);
    const [inputValue, setInputValue] = React.useState('');

    const nameById = React.useMemo(() => {
        const map = new Map<string, string>();
        options.forEach((o) => map.set(String(o.id), o.name));
        return map;
    }, [options]);

    const handleUnselect = (id: string) => {
        onChange(selected.filter((s) => s !== id));
    };

    const selectables = options.filter((o) => !selected.includes(String(o.id)));

    return (
        <Command className="overflow-visible bg-transparent">
            <div className="group border border-input text-secondary text-primary-foreground ring-offset-background focus-within:ring-ring rounded-2xl bg-white px-2 text-sm focus-within:ring-2 focus-within:ring-offset-2">
                <div className="flex max-h-20 max-w-md flex-wrap gap-1 overflow-auto">
                    {selected.map((id, index) => {
                        const colorClass = BADGE_COLORS[index % BADGE_COLORS.length];
                        const label = nameById.get(String(id)) ?? id;
                        return (
                            <span key={id} className={`my-1 inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${colorClass}`}>
                                {label}
                                <button
                                    type="button"
                                    className="focus:ring-ring my-1 ml-1 rounded-full p-0.5 focus:outline-none focus:ring-2"
                                    onKeyDown={(e) => {
                                        if (e.key === 'Enter') handleUnselect(id);
                                    }}
                                    onMouseDown={(e) => {
                                        e.preventDefault();
                                        e.stopPropagation();
                                    }}
                                    onClick={() => handleUnselect(id)}
                                >
                                    <X className="h-3 w-3 text-current hover:text-black" />
                                </button>
                            </span>
                        );
                    })}
                    <CommandInput
                        ref={inputRef}
                        value={inputValue}
                        onValueChange={setInputValue}
                        onBlur={() => setOpen(false)}
                        onFocus={() => setOpen(true)}
                        placeholder={selected.length === 0 ? placeholder : ''}
                        className="placeholder:text-secondary ml-2 flex-1 bg-transparent text-sm outline-none"
                    />
                </div>
            </div>

            <div className="relative mt-2">
                {open && selectables.length > 0 && (
                    <div className="bg-popover text-popover-foreground animate-in absolute top-0 z-10 w-full rounded-md border shadow-md outline-none">
                        <CommandList>
                            <CommandEmpty>No results found.</CommandEmpty>
                            <CommandGroup className="h-full overflow-auto">
                                {selectables.map((option) => (
                                    <CommandItem
                                        key={option.id}
                                        value={option.name}
                                        onMouseDown={(e) => {
                                            e.preventDefault();
                                            e.stopPropagation();
                                        }}
                                        onSelect={() => {
                                            setInputValue('');
                                            onChange([...selected, String(option.id)]);
                                        }}
                                        className="cursor-pointer text-sm"
                                    >
                                        {option.name}
                                    </CommandItem>
                                ))}
                            </CommandGroup>
                        </CommandList>
                    </div>
                )}
            </div>
        </Command>
    );
}
