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

import { cn } from "@/lib/utils"
import { Badge } from "@/components/ui/badge"
import { buttonVariants } from "@/components/ui/button"
import {
    Command,
    CommandEmpty,
    CommandGroup,
    CommandInput,
    CommandItem,
    CommandList,
} from "@/components/ui/command"
import {
    Popover,
    PopoverContent,
    PopoverTrigger,
} from "@/components/ui/popover"

export type Option = {
    label: string
    value: string
}

interface FancyMultiSelectProps {
    options: Option[]
    selected: string[]
    onChange: (selected: string[]) => void
    onCreate?: (value: string) => void
    placeholder?: string
    emptyMessage?: string
    className?: string
}

export function FancyMultiSelect({
    options,
    selected,
    onChange,
    onCreate,
    placeholder = "Seçiniz...",
    emptyMessage = "Sonuç bulunamadı.",
    className,
}: FancyMultiSelectProps) {
    const [open, setOpen] = React.useState(false)
    const [inputValue, setInputValue] = React.useState("")

    const handleUnselect = (item: string) => {
        onChange(selected.filter((i) => i !== item))
    }

    const handleSelect = (item: string) => {
        if (selected.includes(item)) {
            onChange(selected.filter((i) => i !== item))
        } else {
            onChange([...selected, item])
        }
    }

    const handleCreate = () => {
        if (onCreate && inputValue.trim() !== "") {
            onCreate(inputValue.trim())
            setInputValue("")
        }
    }

    // Map selected values to Option objects for display
    const selectedOptions = selected
        .map((value) => options.find((opt) => opt.value === value))
        // If option not found (maybe newly created and not yet in options list fully refetched, or just ID vs Label issue), try to find it or display placeholder if we only have ID.
        // Actually for this strict implementation, we expect options to be updated. 
        // But for better UX with "create", we might want to display the ID if label missing, or assume options will be updated by parent.
        .filter((opt): opt is Option => !!opt)

    return (
        <Popover open={open} onOpenChange={setOpen}>
            <PopoverTrigger asChild>
                <div
                    role="combobox"
                    aria-expanded={open}
                    className={cn(
                        buttonVariants({ variant: "outline" }),
                        "w-full justify-between h-auto min-h-10 px-3 py-2 hover:bg-background cursor-pointer",
                        className
                    )}
                    tabIndex={0}
                >
                    <div className="flex flex-wrap gap-1">
                        {selectedOptions.length > 0 ? (
                            selectedOptions.map((option) => (
                                <Badge
                                    variant="secondary"
                                    key={option.value}
                                    className="mr-1 mb-1"
                                    onClick={(e) => {
                                        e.stopPropagation()
                                        handleUnselect(option.value)
                                    }}
                                >
                                    {option.label}
                                    <div
                                        className="ml-1 ring-offset-background rounded-full outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 cursor-pointer"
                                        onKeyDown={(e) => {
                                            if (e.key === "Enter") {
                                                handleUnselect(option.value)
                                            }
                                        }}
                                        onMouseDown={(e) => {
                                            e.preventDefault()
                                            e.stopPropagation()
                                        }}
                                        onClick={(e) => {
                                            e.preventDefault();
                                            e.stopPropagation();
                                            handleUnselect(option.value)
                                        }}
                                        role="button"
                                        tabIndex={0}
                                    >
                                        <X className="h-3 w-3 text-muted-foreground hover:text-foreground" />
                                    </div>
                                </Badge>
                            ))
                        ) : (
                            <span className="text-muted-foreground">{placeholder}</span>
                        )}
                    </div>
                    <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                </div>
            </PopoverTrigger>
            <PopoverContent className="w-full p-0">
                <Command>
                    <CommandInput
                        placeholder="Ara veya Ekle..."
                        value={inputValue}
                        onValueChange={setInputValue}
                    />
                    <CommandList>
                        <CommandEmpty>
                            {onCreate && inputValue.trim() !== "" ? (
                                <div className="p-2 cursor-pointer hover:bg-secondary rounded-sm" onMouseDown={(e) => {
                                    e.preventDefault()
                                    handleCreate()
                                }}>
                                    "{inputValue}" oluştur
                                </div>
                            ) : (
                                emptyMessage
                            )}
                        </CommandEmpty>
                        <CommandGroup className="max-h-64 overflow-auto">
                            {options.map((option) => (
                                <CommandItem
                                    key={option.value}
                                    onSelect={() => handleSelect(option.value)}
                                >
                                    <Check
                                        className={cn(
                                            "mr-2 h-4 w-4",
                                            selected.includes(option.value)
                                                ? "opacity-100"
                                                : "opacity-0"
                                        )}
                                    />
                                    {option.label}
                                </CommandItem>
                            ))}
                        </CommandGroup>
                    </CommandList>
                </Command>
            </PopoverContent>
        </Popover>
    )
}
