"use client";

import * as React from "react";
import { Check, ChevronsUpDown } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import {
    Popover,
    PopoverContent,
    PopoverTrigger,
} from "@/components/ui/popover";
import { Input } from "@/components/ui/input";

interface ComboboxProps {
    options: { id: string; name: string }[];
    value: string;
    onValueChange: (value: string) => void;
    placeholder?: string;
    searchPlaceholder?: string;
    emptyMessage?: string;
    loading?: boolean;
    searchValue?: string;
    onSearchValueChange?: (value: string) => void;
    disableLocalFilter?: boolean;
}

export function Combobox({
    options,
    value,
    onValueChange,
    placeholder = "Select option...",
    searchPlaceholder = "Search...",
    emptyMessage = "No results found.",
    loading = false,
    searchValue,
    onSearchValueChange,
    disableLocalFilter = false,
}: ComboboxProps) {
    const [open, setOpen] = React.useState(false);
    const [internalSearch, setInternalSearch] = React.useState("");

    const search = searchValue ?? internalSearch;

    const filteredOptions = React.useMemo(() => {
        if (disableLocalFilter) return options;
        if (!search) return options;
        const lower = search.toLowerCase();
        return options.filter(
            (option) =>
                option.name.toLowerCase().includes(lower) ||
                option.id.toLowerCase().includes(lower)
        );
    }, [disableLocalFilter, options, search]);

    const selectedOption = options.find((opt) => opt.id === value);
    const selectedLabel = selectedOption?.name ?? (value ? value : placeholder);

    return (
        <Popover open={open} onOpenChange={setOpen}>
            <PopoverTrigger asChild>
                <Button
                    variant="outline"
                    role="combobox"
                    aria-expanded={open}
                    className="w-full justify-between font-normal"
                >
                    <span className="truncate">
                        {selectedLabel}
                    </span>
                    <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                </Button>
            </PopoverTrigger>
            <PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0" align="start">
                <div className="p-2">
                    <Input
                        placeholder={searchPlaceholder}
                        value={search}
                        onChange={(e) => {
                            const next = e.target.value;
                            if (onSearchValueChange) {
                                onSearchValueChange(next);
                            } else {
                                setInternalSearch(next);
                            }
                        }}
                        className="h-9"
                    />
                </div>
                <div className="max-h-[300px] overflow-y-auto">
                    {loading ? (
                        <div className="py-6 text-center text-sm text-muted-foreground">
                            Loading...
                        </div>
                    ) : filteredOptions.length === 0 ? (
                        <div className="py-6 text-center text-sm text-muted-foreground">
                            {emptyMessage}
                        </div>
                    ) : (
                        <div className="p-1">
                            {filteredOptions.map((option) => (
                                <button
                                    key={option.id}
                                    onClick={() => {
                                        onValueChange(option.id === value ? "" : option.id);
                                        setOpen(false);
                                        if (onSearchValueChange) {
                                            onSearchValueChange("");
                                        } else {
                                            setInternalSearch("");
                                        }
                                    }}
                                    className={cn(
                                        "relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none hover:bg-accent hover:text-accent-foreground",
                                        value === option.id && "bg-accent"
                                    )}
                                >
                                    <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
                                        {value === option.id && <Check className="h-4 w-4" />}
                                    </span>
                                    <span className="truncate">{option.name}</span>
                                </button>
                            ))}
                        </div>
                    )}
                </div>
            </PopoverContent>
        </Popover>
    );
}
