import * as React from "react";
import { Check, ChevronsUpDown, X } from "lucide-react";

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

interface Option {
    label: string;
    value: string;
    sublabel?: string;
    disabled?: boolean;
}

interface SearchableSelectProps {
    value: string;
    onValueChange: (value: string) => void;
    options: Option[];
    placeholder?: string;
    searchPlaceholder?: string;
    emptyText?: string;
    disabled?: boolean;
    className?: string;
    /** 當選項數量超過此閾值時顯示搜尋框，預設為 10。若設為 0 則總是顯示。 */
    searchThreshold?: number;
    /** 強制控制是否顯示搜尋框。若設定此值，則忽略 searchThreshold */
    showSearch?: boolean;
    /** 是否可清除選取 */
    isClearable?: boolean;
}

export function SearchableSelect({
    value,
    onValueChange,
    options,
    placeholder = "請選擇...",
    searchPlaceholder = "搜尋...",
    emptyText = "找不到符合的項目",
    disabled = false,
    className,
    searchThreshold = 10,
    showSearch,
    isClearable = false,
}: SearchableSelectProps) {
    const [open, setOpen] = React.useState(false);

    // 決定是否顯示搜尋框
    const shouldShowSearch =
        showSearch !== undefined ? showSearch : options.length > searchThreshold;

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

    return (
        <Popover open={open} onOpenChange={setOpen}>
            <PopoverTrigger asChild>
                <button
                    type="button"
                    role="combobox"
                    aria-expanded={open}
                    disabled={disabled}
                    className={cn(
                        // Base styles matching SelectTrigger
                        "flex w-full items-center justify-between gap-2 rounded-md px-3 py-2 text-sm whitespace-nowrap transition-[color,box-shadow] outline-none",
                        // Outlined default state - 2px border with grey-3
                        "border-2 border-grey-3 bg-grey-5",
                        // Text colors
                        "text-grey-0",
                        !selectedOption && "text-grey-3",
                        // Focus state - primary border with ring
                        "focus-visible:border-primary-main focus-visible:ring-primary-main/20 focus-visible:ring-[3px]",
                        // Disabled state
                        "disabled:border-grey-4 disabled:bg-background-light-grey disabled:text-grey-2 disabled:cursor-not-allowed disabled:opacity-50",
                        // Height
                        "h-9",
                        className
                    )}
                >
                    <span className="truncate">
                        {selectedOption ? selectedOption.label : placeholder}
                    </span>
                    <div className="flex items-center gap-1 shrink-0">
                        {isClearable && value && !disabled && (
                            <X
                                className="h-4 w-4 text-grey-3 hover:text-grey-1 transition-colors pointer-events-auto cursor-pointer"
                                onClick={(e) => {
                                    e.stopPropagation();
                                    onValueChange("");
                                }}
                            />
                        )}
                        <ChevronsUpDown className="h-4 w-4 opacity-50 text-grey-2" />
                    </div>
                </button>
            </PopoverTrigger>
            <PopoverContent
                className="p-0 z-[9999]"
                align="start"
                style={{ width: "var(--radix-popover-trigger-width)", minWidth: "12rem" }}
            >
                <Command>
                    {shouldShowSearch && (
                        <CommandInput placeholder={searchPlaceholder} />
                    )}
                    <CommandList>
                        <CommandEmpty>{emptyText}</CommandEmpty>
                        <CommandGroup>
                            {options.map((option) => (
                                <CommandItem
                                    key={option.value}
                                    value={`${option.label} ${option.value}`}
                                    onSelect={() => {
                                        onValueChange(option.value);
                                        setOpen(false);
                                    }}
                                    disabled={option.disabled}
                                    className="cursor-pointer"
                                >
                                    <Check
                                        className={cn(
                                            "mr-2 h-4 w-4 text-primary",
                                            value === option.value
                                                ? "opacity-100"
                                                : "opacity-0"
                                        )}
                                    />
                                    <div className="flex items-center justify-between flex-1">
                                        <span>{option.label}</span>
                                        {option.sublabel && (
                                            <span className="text-xs text-muted-foreground ml-2">
                                                {option.sublabel}
                                            </span>
                                        )}
                                    </div>
                                </CommandItem>
                            ))}
                        </CommandGroup>
                    </CommandList>
                </Command>
            </PopoverContent>
        </Popover>
    );
}
