import { Check, ChevronDown } from 'lucide-react';
import React from 'react';

import TextInput from '@/Components/TextInput';
import { Button } from '@/Components/ui/button';
import {
    Command,
    CommandEmpty,
    CommandGroup,
    CommandInput,
    CommandItem,
    CommandList,
} from '@/Components/ui/command';
import {
    Popover,
    PopoverContent,
    PopoverTrigger,
} from '@/Components/ui/popover';
import { cn } from '@/lib/utils';

interface Option {
    id: string | number;
}

interface ComboBoxInputProps<T extends Option> {
    options: T[];
    value?: T | null;
    renderOption: (option: T) => string;
    onChange: (option: T | null) => void;
    onSearchChange: (search: string) => void;
    readOnly?: boolean;
}

export default function ComboBoxInput<T extends Option>({
    options,
    value,
    renderOption,
    onChange,
    onSearchChange,
    readOnly = false,
}: ComboBoxInputProps<T>) {
    const [open, setOpen] = React.useState(false);

    function onSelect(option: T) {
        onChange(option);
        setOpen(false);
    }

    const items = options.map((option) => {
        const handleSelect = () => onSelect(option);
        const selected = value && option.id === value.id;
        return (
            <CommandItem
                key={option.id}
                value={String(option.id)}
                onSelect={handleSelect}
            >
                <Check
                    className={cn(
                        'mr-2 h-4 w-4',
                        selected ? 'opacity-100' : 'opacity-0',
                    )}
                />
                {renderOption(option)}
            </CommandItem>
        );
    });

    if (readOnly) {
        return <TextInput readOnly value={value ? renderOption(value) : ''} />;
    }

    return (
        <Popover open={open} onOpenChange={setOpen}>
            <PopoverTrigger asChild>
                <Button
                    variant="outline"
                    role="combobox"
                    aria-expanded={open}
                    className="w-full items-center justify-between rounded-md"
                >
                    <span className="truncate">
                        {value ? renderOption(value) : <span />}
                    </span>
                    <ChevronDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                </Button>
            </PopoverTrigger>
            <PopoverContent className="w-full p-0">
                <Command shouldFilter={false}>
                    <CommandInput
                        onValueChange={onSearchChange}
                        className="h-9 border-0 focus:ring-0"
                    />
                    <CommandList>
                        <CommandEmpty>Nessun risultato.</CommandEmpty>
                        <CommandGroup className="text-black">
                            {items}
                        </CommandGroup>
                    </CommandList>
                </Command>
            </PopoverContent>
        </Popover>
    );
}
