import { useMemo, useState } from "react";
import {
  Button,
  cn,
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@arronqzy/ui";
import { useI18n } from "@arronqzy/i18n/react";

export type ViewElementMultiSelectOption = {
  id: string;
  label: string;
};

export type ViewElementMultiSelectProps = {
  options: ViewElementMultiSelectOption[];
  value: string[];
  onChange: (next: string[]) => void;
  placeholder?: string;
  disabled?: boolean;
};

function CheckIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden>
      <path
        fill="currentColor"
        d="M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"
      />
    </svg>
  );
}

function ChevronDownIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden>
      <path fill="currentColor" d="M7 10l5 5 5-5z" />
    </svg>
  );
}

export function ViewElementMultiSelect({
  options,
  value,
  onChange,
  placeholder,
  disabled = false,
}: ViewElementMultiSelectProps) {
  const { t } = useI18n();
  const [open, setOpen] = useState(false);
  const resolvedPlaceholder =
    placeholder ?? t("blueprint.config.selectViewNode");
  const labelById = useMemo(
    () => new Map(options.map((opt) => [opt.id, opt.label])),
    [options]
  );
  const selectedSet = useMemo(() => new Set(value), [value]);
  const emptyOptions = options.length === 0;

  let triggerText = resolvedPlaceholder;
  if (value.length > 0) {
    const labels = value.map((id) => labelById.get(id) ?? id);
    if (labels.length === 1) {
      triggerText = labels[0]!;
    } else {
      const joined = labels.join("、");
      triggerText =
        joined.length <= 26
          ? joined
          : t("blueprint.config.selectedCount", { count: value.length });
    }
  }

  const toggle = (id: string) => {
    onChange(
      selectedSet.has(id)
        ? value.filter((item) => item !== id)
        : [...value, id]
    );
  };

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          type="button"
          variant="outline"
          role="combobox"
          aria-expanded={open}
          disabled={disabled || emptyOptions}
          className={cn(
            "h-8 w-full justify-between px-3 text-xs font-normal",
            value.length === 0 && "text-muted-foreground"
          )}
        >
          <span className="min-w-0 flex-1 truncate text-left">
            {emptyOptions ? t("blueprint.config.noViewOnCanvas") : triggerText}
          </span>
          <ChevronDownIcon className="h-4 w-4 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent
        className="z-[10100] w-[var(--radix-popover-trigger-width)] p-0"
        align="start"
      >
        <Command>
          <CommandInput
            placeholder={t("blueprint.config.searchViewNodes")}
            className="h-9 text-xs"
          />
          <CommandList>
            <CommandEmpty>{t("blueprint.config.noMatchingNodes")}</CommandEmpty>
            <CommandGroup>
              {options.map((opt) => {
                const selected = selectedSet.has(opt.id);
                return (
                  <CommandItem
                    key={opt.id}
                    value={`${opt.label} ${opt.id}`}
                    className="text-xs"
                    onMouseDown={(e) => e.preventDefault()}
                    onSelect={() => toggle(opt.id)}
                  >
                    <CheckIcon
                      className={cn(
                        "h-4 w-4 shrink-0",
                        selected ? "opacity-100" : "opacity-0"
                      )}
                    />
                    <span className="min-w-0 truncate">{opt.label}</span>
                  </CommandItem>
                );
              })}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}
