import { Check, ChevronsUpDown, Loader2 } from 'lucide-react';
import * as React from 'react';

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';

export interface SearchableSelectOption {
    value: string;
    label: string;
}

interface SearchableSelectProps {
    options: SearchableSelectOption[];
    value: string;
    onValueChange: (value: string) => void;
    placeholder?: string;
    searchPlaceholder?: string;
    emptyMessage?: string;
    loading?: boolean;
    disabled?: boolean;
    className?: string;
    error?: string;
    searchValue?: string;
    onSearchChange?: (value: string) => void;
}

export function SearchableSelect({
    options,
    value,
    onValueChange,
    placeholder = 'Pilih opsi...',
    searchPlaceholder = 'Cari...',
    emptyMessage = 'Tidak ada hasil ditemukan.',
    loading = false,
    disabled = false,
    className,
    error,
    onSearchChange,
    searchValue,
}: SearchableSelectProps) {
    const [open, setOpen] = React.useState(false);

    const selectedOption = options.find((option) => option.value === value);

    return (
        <div className={cn('space-y-2', className)}>
            <Popover open={open} onOpenChange={setOpen}>
                <PopoverTrigger asChild>
                    <Button
                        variant="outline"
                        role="combobox"
                        aria-expanded={open}
                        disabled={disabled || loading}
                        className={cn(
                            'w-full justify-between font-normal',
                            !value && 'text-muted-foreground',
                            error && 'border-destructive',
                        )}
                    >
                        <span className="truncate">
                            {loading
                                ? 'Memuat...'
                                : selectedOption
                                  ? selectedOption.label
                                  : placeholder}
                        </span>
                        {loading ? (
                            <Loader2 className="ml-2 h-4 w-4 shrink-0 animate-spin opacity-50" />
                        ) : (
                            <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                        )}
                    </Button>
                </PopoverTrigger>
                <PopoverContent className="w-[--radix-popover-trigger-width] p-0" align="start">
                    <Command>
                        <CommandInput 
                            placeholder={searchPlaceholder} 
                            className="h-9" 
                            value={searchValue}
                            onValueChange={onSearchChange}
                        />
                        <CommandList>
                            <CommandEmpty className="py-6 text-center text-sm">
                                {emptyMessage}
                            </CommandEmpty>
                            <CommandGroup>
                                {options.map((option) => (
                                    <CommandItem
                                        key={option.value}
                                        value={option.label}
                                        onSelect={() => {
                                            onValueChange(option.value);
                                            setOpen(false);
                                        }}
                                    >
                                        <Check
                                            className={cn(
                                                'mr-2 h-4 w-4',
                                                value === option.value
                                                    ? 'opacity-100'
                                                    : 'opacity-0',
                                            )}
                                        />
                                        {option.label}
                                    </CommandItem>
                                ))}
                            </CommandGroup>
                        </CommandList>
                    </Command>
                </PopoverContent>
            </Popover>
            {error && <p className="text-sm font-medium text-destructive">{error}</p>}
        </div>
    );
}
