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

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

/**
 * Multi-select com busca, baseado no padrão shadcn (Command + Popover).
 *
 * Props:
 *  - options:        Array<{ value: string|number, label: string, disabled?: bool, hint?: string }>
 *  - value:          Array<string|number> - valores selecionados
 *  - onChange:       (next: Array) => void
 *  - placeholder:    string mostrado quando nada está selecionado
 *  - searchPlaceholder
 *  - emptyText
 *  - maxBadges:      número máximo de badges visíveis no trigger (default: 3)
 *  - disabled
 *  - className
 */
export function MultiSelect({
    options = [],
    value = [],
    onChange,
    placeholder = "Selecionar...",
    searchPlaceholder = "Buscar...",
    emptyText = "Nada encontrado.",
    maxBadges = 3,
    disabled = false,
    className,
}) {
    const [open, setOpen] = React.useState(false);

    const selectedSet = React.useMemo(
        () => new Set(value.map((v) => String(v))),
        [value]
    );

    const byValue = React.useMemo(() => {
        const map = new Map();
        options.forEach((o) => map.set(String(o.value), o));
        return map;
    }, [options]);

    function toggle(v) {
        const key = String(v);
        const next = selectedSet.has(key)
            ? value.filter((x) => String(x) !== key)
            : [...value, v];
        onChange?.(next);
    }

    function clearAll(e) {
        e.stopPropagation();
        onChange?.([]);
    }

    function selectAll() {
        const all = options.filter((o) => !o.disabled).map((o) => o.value);
        onChange?.(all);
    }

    const visibleBadges = value.slice(0, maxBadges);
    const overflow = value.length - visibleBadges.length;

    return (
        <Popover open={open} onOpenChange={setOpen}>
            <PopoverTrigger asChild>
                <Button
                    type="button"
                    variant="outline"
                    role="combobox"
                    aria-expanded={open}
                    disabled={disabled}
                    className={cn(
                        "min-h-9 h-auto w-full justify-between gap-1 px-2 py-1.5 font-normal",
                        value.length === 0 && "text-muted-foreground",
                        className
                    )}
                >
                    <div className="flex flex-1 flex-wrap items-center gap-1">
                        {value.length === 0 ? (
                            <span className="px-1">{placeholder}</span>
                        ) : (
                            <>
                                {visibleBadges.map((v) => {
                                    const opt = byValue.get(String(v));
                                    if (!opt) return null;
                                    return (
                                        <Badge
                                            key={String(v)}
                                            variant="secondary"
                                            className="rounded-sm px-1.5 py-0 font-normal"
                                        >
                                            {opt.label}
                                            <span
                                                role="button"
                                                tabIndex={-1}
                                                onMouseDown={(e) => {
                                                    e.preventDefault();
                                                    e.stopPropagation();
                                                }}
                                                onClick={(e) => {
                                                    e.preventDefault();
                                                    e.stopPropagation();
                                                    toggle(v);
                                                }}
                                                className="ml-1 inline-flex h-3.5 w-3.5 cursor-pointer items-center justify-center rounded-sm hover:bg-muted-foreground/20"
                                            >
                                                <X className="h-2.5 w-2.5" />
                                            </span>
                                        </Badge>
                                    );
                                })}
                                {overflow > 0 && (
                                    <Badge
                                        variant="secondary"
                                        className="rounded-sm px-1.5 py-0 font-normal"
                                    >
                                        +{overflow}
                                    </Badge>
                                )}
                            </>
                        )}
                    </div>
                    <div className="flex items-center gap-1 shrink-0">
                        {value.length > 0 && !disabled && (
                            <span
                                role="button"
                                tabIndex={-1}
                                onMouseDown={(e) => {
                                    e.preventDefault();
                                    e.stopPropagation();
                                }}
                                onClick={clearAll}
                                className="inline-flex h-5 w-5 cursor-pointer items-center justify-center rounded-sm text-muted-foreground hover:bg-muted hover:text-foreground"
                                title="Limpar"
                            >
                                <X className="h-3.5 w-3.5" />
                            </span>
                        )}
                        <ChevronsUpDown className="h-4 w-4 shrink-0 opacity-50" />
                    </div>
                </Button>
            </PopoverTrigger>
            <PopoverContent
                className="w-[--radix-popover-trigger-width] p-0"
                align="start"
            >
                <Command>
                    <CommandInput placeholder={searchPlaceholder} />
                    <CommandList>
                        <CommandEmpty>{emptyText}</CommandEmpty>
                        <CommandGroup>
                            {options.map((opt) => {
                                const checked = selectedSet.has(String(opt.value));
                                return (
                                    <CommandItem
                                        key={String(opt.value)}
                                        value={`${opt.label} ${opt.hint ?? ""}`}
                                        onSelect={() => !opt.disabled && toggle(opt.value)}
                                        disabled={opt.disabled}
                                        className="cursor-pointer"
                                    >
                                        <div
                                            className={cn(
                                                "mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary",
                                                checked
                                                    ? "bg-primary text-primary-foreground"
                                                    : "opacity-50 [&_svg]:invisible"
                                            )}
                                        >
                                            <Check className="h-3.5 w-3.5" />
                                        </div>
                                        <span className="flex-1">{opt.label}</span>
                                        {opt.hint && (
                                            <span className="ml-2 text-xs text-muted-foreground">
                                                {opt.hint}
                                            </span>
                                        )}
                                    </CommandItem>
                                );
                            })}
                        </CommandGroup>
                        {options.length > 0 && (
                            <>
                                <CommandSeparator />
                                <CommandGroup>
                                    <div className="flex items-center justify-between gap-2 px-2 py-1">
                                        <button
                                            type="button"
                                            onClick={selectAll}
                                            className="text-xs text-muted-foreground hover:text-foreground"
                                        >
                                            Selecionar tudo
                                        </button>
                                        <button
                                            type="button"
                                            onClick={() => onChange?.([])}
                                            className="text-xs text-muted-foreground hover:text-foreground"
                                            disabled={value.length === 0}
                                        >
                                            Limpar
                                        </button>
                                    </div>
                                </CommandGroup>
                            </>
                        )}
                    </CommandList>
                </Command>
            </PopoverContent>
        </Popover>
    );
}
