"use client"

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

import { cn } from "@/lib/utils"
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"

type Data = {
    value: string;
    label: string;
    keywords?: string[] | undefined;
}

interface MultiSelectComboboxProps {
    data: Data[]
    value?: string[];
    placeholder?: string;
    loading?: boolean;
    onChange: (value: string[]) => void;
    onInputChange?: (value: string) => void;
}

export function MultiSelectCombobox({ data, value = [], placeholder, loading, onChange, onInputChange }: MultiSelectComboboxProps) {
  const [open, setOpen] = React.useState(false)

  const handleUnselect = (itemValue: string) => {
    onChange(value.filter((i) => i !== itemValue))
  }

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          className="w-full justify-between h-auto min-h-10 py-1.5 px-3"
          onClick={() => setOpen(!open)}
        >
          <div className="flex flex-wrap gap-1 items-center max-w-full overflow-hidden">
            {loading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : null}
            {value.length > 0 ? (
              value.map((val) => {
                const item = data.find((i) => i.value === val);
                return (
                  <div
                    key={val}
                    className="flex items-center gap-1 bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200 px-2 py-1 rounded-md text-xs font-medium"
                  >
                    {item ? item.label : val}
                    <div
                      role="button"
                      tabIndex={0}
                      className="ring-offset-background rounded-full outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 hover:bg-gray-200 dark:hover:bg-gray-700 p-0.5"
                      onKeyDown={(e) => {
                        if (e.key === "Enter") {
                          handleUnselect(val);
                        }
                      }}
                      onMouseDown={(e) => {
                        e.preventDefault();
                        e.stopPropagation();
                      }}
                      onClick={(e) => {
                        e.preventDefault();
                        e.stopPropagation();
                        handleUnselect(val);
                      }}
                    >
                      <X className="h-3 w-3 text-muted-foreground hover:text-foreground" />
                    </div>
                  </div>
                );
              })
            ) : (
               <span className="text-muted-foreground">{placeholder || "Select..."}</span>
            )}
          </div>
          <ChevronDown className="h-4 w-4 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent 
        className="w-[var(--radix-popper-anchor-width)] p-0"
        side="bottom"
        align="start"
      >
        <Command 
          filter={(value, search, keywords) => {
             const extendValue = value + " " + keywords?.join(" ");
             if (extendValue.toLowerCase().includes(search.toLowerCase())) return 1;
             return 0;
          }}
        >
          <CommandInput 
            placeholder="Cari..."  
            className="border-none hover:border-none focus:outline-none"
            onValueChange={onInputChange}
          />
          <CommandList>
            <CommandEmpty>No data found.</CommandEmpty>
            <CommandGroup>
              {data?.map((item) => {
                const isSelected = value.includes(item.value);
                return (
                  <CommandItem
                    key={item.value}
                    value={item.value}
                    keywords={[
                      item.label.toLowerCase(),
                      ...(item.keywords || []),
                    ]}
                    onSelect={() => {
                        if (isSelected) {
                            onChange(value.filter((val) => val !== item.value))
                        } else {
                            onChange([...value, item.value])
                        }
                        // Don't close popover when selecting multiple items
                    }}
                  >
                    <div className="flex w-full items-center justify-between">
                        {item.label}
                        <Check
                            className={cn(
                                "ml-2 h-4 w-4",
                                isSelected ? "opacity-100" : "opacity-0"
                            )}
                        />
                    </div>
                  </CommandItem>
                );
              })}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  )
}
