// admin-spa/src/components/ui/searchable-select.tsx
import * as React from "react";
import { Button } from "@/components/ui/button";
import {
  Popover,
  PopoverTrigger,
  PopoverContent,
} from "@/components/ui/popover";
import {
  Command,
  CommandInput,
  CommandList,
  CommandItem,
  CommandEmpty,
} from "@/components/ui/command";
import { Check, ChevronsUpDown } from "lucide-react";
import { cn } from "@/lib/utils";

export interface Option {
  value: string;
  /** What to render in the button/list. Can be a string or React node. */
  label: React.ReactNode;
  /** Optional text used for filtering. Falls back to string label or value. */
  triggerLabel?: React.ReactNode;
}

interface Props {
  value?: string;
  onChange?: (v: string) => void;
  options: Option[];
  placeholder?: string;
  emptyLabel?: string;
  className?: string;
  disabled?: boolean;
  search?: string;
  onSearch?: (v: string) => void;
  showCheckIndicator?: boolean;
}

export function SearchableSelect({
  value,
  onChange,
  options,
  placeholder = "Select...",
  emptyLabel = "No results found.",
  className,
  disabled = false,
  search,
  onSearch,
  showCheckIndicator = true,
}: Props) {
  const [open, setOpen] = React.useState(false);
  const selected = options.find((o) => o.value === value);

  React.useEffect(() => { if (disabled && open) setOpen(false); }, [disabled, open]);

  return (
    <Popover open={disabled ? false : open} onOpenChange={(o) => !disabled && setOpen(o)}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          className={cn("w-full justify-between", className)}
          disabled={disabled}
          aria-disabled={disabled}
          tabIndex={disabled ? -1 : 0}
        >
          {selected ? (selected.triggerLabel ?? selected.label) : placeholder}
          <ChevronsUpDown className="opacity-50 h-4 w-4 shrink-0" />
        </Button>
      </PopoverTrigger>
      <PopoverContent
        className="p-0 w-[--radix-popover-trigger-width]"
        align="start"
        sideOffset={4}
      >
        <Command shouldFilter>
          <CommandInput
            className="command-palette-search"
            placeholder="Search..."
            value={search}
            onValueChange={onSearch}
          />
          <CommandList>
            <CommandEmpty>{emptyLabel}</CommandEmpty>
            {options.map((opt) => (
              <CommandItem
                key={opt.value}
                value={
                  typeof opt.searchText === 'string' && opt.searchText.length > 0
                    ? opt.searchText
                    : (typeof opt.label === 'string' ? opt.label : opt.value)
                }
                onSelect={() => {
                  onChange?.(opt.value);
                  setOpen(false);
                }}
              >
                {showCheckIndicator && (
                  <Check
                    className={cn(
                      "mr-2 h-4 w-4 flex-shrink-0",
                      opt.value === value ? "opacity-100" : "opacity-0"
                    )}
                  />
                )}
                {opt.label}
              </CommandItem>
            ))}
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}