"use client";

import { useEffect, useRef, useState } from "react";
import { Check, ChevronDown, X } from "lucide-react";
import { cn } from "@/lib/utils/cn";

interface MultiSelectDropdownProps {
  choices: string[];
  value: string[];
  onChange: (next: string[]) => void;
  placeholder?: string;
  maxSelections?: number;
  disabled?: boolean;
}

export function MultiSelectDropdown({
  choices,
  value,
  onChange,
  placeholder = "Select one or more…",
  maxSelections,
  disabled,
}: MultiSelectDropdownProps) {
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    function handlePointer(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) {
        setOpen(false);
      }
    }
    if (open) document.addEventListener("mousedown", handlePointer);
    return () => document.removeEventListener("mousedown", handlePointer);
  }, [open]);

  function toggle(opt: string) {
    const isOn = value.includes(opt);
    if (isOn) {
      onChange(value.filter((v) => v !== opt));
      return;
    }
    if (maxSelections != null && value.length >= maxSelections) return;
    onChange([...value, opt]);
  }

  const summary =
    value.length === 0
      ? placeholder
      : value.length <= 2
        ? value.join(", ")
        : `${value.slice(0, 2).join(", ")} +${value.length - 2} more`;

  return (
    <div ref={ref} className="relative">
      <button
        type="button"
        disabled={disabled}
        aria-expanded={open}
        aria-haspopup="listbox"
        onClick={() => setOpen((o) => !o)}
        className={cn(
          "flex w-full items-center justify-between gap-2 rounded-[10px] border-[1.5px] bg-white px-3.5 py-3 text-left text-sm",
          open ? "border-primary" : "border-border hover:border-accent",
          disabled && "opacity-50"
        )}
      >
        <span
          className={cn(
            "min-w-0 truncate font-medium",
            value.length === 0 ? "text-muted" : "text-navy"
          )}
        >
          {summary}
        </span>
        <ChevronDown
          className={cn(
            "h-4 w-4 shrink-0 text-muted transition-transform",
            open && "rotate-180"
          )}
        />
      </button>

      {value.length > 0 && (
        <div className="mt-2 flex flex-wrap gap-1.5">
          {value.map((opt) => (
            <button
              key={opt}
              type="button"
              onClick={() => onChange(value.filter((v) => v !== opt))}
              className="inline-flex max-w-full items-center gap-1 rounded-full border border-primary/20 bg-[#EFF6FF] px-2.5 py-1 text-[12px] font-semibold text-primary"
            >
              <span className="truncate">{opt}</span>
              <X className="h-3 w-3 shrink-0" strokeWidth={2.5} />
            </button>
          ))}
        </div>
      )}

      {open && (
        <ul
          role="listbox"
          aria-multiselectable
          className="absolute z-20 mt-1.5 max-h-56 w-full overflow-y-auto rounded-[10px] border border-border bg-white py-1 shadow-lg"
        >
          {choices.map((opt) => {
            const isOn = value.includes(opt);
            const blocked =
              !isOn &&
              maxSelections != null &&
              value.length >= maxSelections;
            return (
              <li key={opt}>
                <button
                  type="button"
                  role="option"
                  aria-selected={isOn}
                  disabled={blocked}
                  onClick={() => toggle(opt)}
                  className={cn(
                    "flex w-full items-center gap-2.5 px-3 py-2.5 text-left text-sm font-medium",
                    isOn ? "bg-[#F8FBFF] text-primary" : "text-navy hover:bg-[#F8FAFC]",
                    blocked && "cursor-not-allowed opacity-45"
                  )}
                >
                  <span
                    className={cn(
                      "flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border-[1.5px]",
                      isOn
                        ? "border-primary bg-primary text-white"
                        : "border-border"
                    )}
                  >
                    {isOn && <Check className="h-3 w-3" strokeWidth={3} />}
                  </span>
                  {opt}
                </button>
              </li>
            );
          })}
        </ul>
      )}

      <p className="mt-2 text-[12px] text-muted">
        You can pick more than one
        {maxSelections != null
          ? ` (up to ${maxSelections})`
          : ""}
        {value.length > 0 ? ` · ${value.length} selected` : ""}.
      </p>
    </div>
  );
}
