"use client";

import { useState, useRef, useEffect, useCallback } from "react";
import { ChevronDown, Search, X } from "lucide-react";
import type { AccountGroup } from "@/app/(portal)/po/new/new-po-form";

interface Props {
  name: string;
  value: string;
  onChange: (value: string) => void;
  groups: AccountGroup[];
  placeholder?: string;
  required?: boolean;
  /** "default" for the main PO field, "compact" for the per-line-item table cell */
  size?: "default" | "compact";
}

export function SearchableSelect({
  name,
  value,
  onChange,
  groups,
  placeholder = "Select accounting code…",
  required,
  size = "default",
}: Props) {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const containerRef = useRef<HTMLDivElement>(null);
  const searchRef = useRef<HTMLInputElement>(null);

  // Close on outside click / Escape
  useEffect(() => {
    if (!open) return;
    function handleKey(e: KeyboardEvent) {
      if (e.key === "Escape") { setOpen(false); setQuery(""); }
    }
    function handleClick(e: MouseEvent) {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        setOpen(false);
        setQuery("");
      }
    }
    document.addEventListener("keydown", handleKey);
    document.addEventListener("mousedown", handleClick);
    return () => {
      document.removeEventListener("keydown", handleKey);
      document.removeEventListener("mousedown", handleClick);
    };
  }, [open]);

  // Auto-focus search input when opened
  useEffect(() => {
    if (open) searchRef.current?.focus();
  }, [open]);

  // Find the display label for the current value
  const selectedItem = groups.flatMap((g) => g.items).find((i) => i.id === value);
  const selectedLabel = selectedItem ? `${selectedItem.code} — ${selectedItem.name}` : "";

  // Filter by query (code or name, case-insensitive)
  const q = query.trim().toLowerCase();
  const filtered = q
    ? groups
        .map((g) => ({
          ...g,
          items: g.items.filter(
            (i) =>
              i.code.toLowerCase().includes(q) ||
              i.name.toLowerCase().includes(q)
          ),
        }))
        .filter((g) => g.items.length > 0)
    : groups;

  const handleSelect = useCallback(
    (id: string) => {
      onChange(id);
      setOpen(false);
      setQuery("");
    },
    [onChange]
  );

  const handleClear = useCallback(
    (e: React.MouseEvent) => {
      e.stopPropagation();
      onChange("");
    },
    [onChange]
  );

  const isCompact = size === "compact";

  return (
    <div ref={containerRef} className="relative w-full">
      {/* Hidden input for form submission */}
      <input type="hidden" name={name} value={value} />
      {required && !value && (
        /* Invisible trick to trigger native "required" validation on submit */
        <input
          tabIndex={-1}
          required
          value={value}
          onChange={() => {}}
          className="absolute opacity-0 w-0 h-0 pointer-events-none"
          aria-hidden
        />
      )}

      {/* Trigger */}
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        className={`w-full flex items-center justify-between gap-2 rounded-lg border
          ${open ? "border-primary-500 ring-2 ring-primary-500/20" : "border-neutral-300"}
          bg-white text-left transition-colors
          focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20
          ${isCompact ? "px-2 py-1.5 text-xs" : "px-3 py-2.5 text-sm"}`}
      >
        <span
          className={`truncate flex-1 min-w-0 ${selectedLabel ? "text-neutral-900" : "text-neutral-400"}`}
        >
          {selectedLabel || placeholder}
        </span>
        <span className="flex items-center gap-1 shrink-0">
          {value && (
            <span
              role="button"
              tabIndex={0}
              onClick={handleClear}
              onKeyDown={(e) => e.key === "Enter" && handleClear(e as unknown as React.MouseEvent)}
              className="text-neutral-300 hover:text-neutral-500 transition-colors"
            >
              <X className={isCompact ? "h-3 w-3" : "h-4 w-4"} />
            </span>
          )}
          <ChevronDown
            className={`text-neutral-400 transition-transform ${open ? "rotate-180" : ""} ${isCompact ? "h-3 w-3" : "h-4 w-4"}`}
          />
        </span>
      </button>

      {/* Dropdown panel
          default: full-width anchored left
          compact: fixed 380px anchored to right edge of trigger (won't overflow table) */}
      {open && (
        <div
          className={`absolute z-50 mt-1 rounded-lg border border-neutral-200 bg-white shadow-xl
            ${isCompact
              ? "right-0 w-[380px]"
              : "left-0 right-0"
            }`}
        >
          {/* Search input */}
          <div className="flex items-center gap-2 p-2 border-b border-neutral-100">
            <Search className="h-4 w-4 text-neutral-400 shrink-0" />
            <input
              ref={searchRef}
              type="text"
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Type code or name…"
              className="flex-1 text-sm outline-none placeholder:text-neutral-400"
            />
            {query && (
              <button type="button" onClick={() => setQuery("")} className="text-neutral-300 hover:text-neutral-500">
                <X className="h-3.5 w-3.5" />
              </button>
            )}
          </div>

          {/* Options */}
          <div className="max-h-64 overflow-y-auto overscroll-contain">
            {filtered.length === 0 ? (
              <p className="px-3 py-5 text-sm text-center text-neutral-400">No codes match "{query}"</p>
            ) : (
              filtered.map((group) => {
                // In compact mode show only the sub-category (after ›), not the full breadcrumb
                const groupLabel = isCompact && group.group.includes("›")
                  ? group.group.split("›").pop()!.trim()
                  : group.group;
                return (
                  <div key={group.group}>
                    {/* Group header */}
                    <div className="sticky top-0 px-3 py-1 text-xs font-semibold text-neutral-500 bg-neutral-50 border-b border-neutral-100 truncate">
                      {groupLabel}
                    </div>
                    {/* Items */}
                    {group.items.map((item) => (
                      <button
                        key={item.id}
                        type="button"
                        onMouseDown={(e) => { e.preventDefault(); handleSelect(item.id); }}
                        className={`w-full text-left flex items-baseline gap-2.5 px-3 py-2 text-sm hover:bg-primary-50 transition-colors
                          ${value === item.id ? "bg-primary-50 text-primary-700 font-medium" : "text-neutral-800"}`}
                      >
                        <span className="font-mono text-xs text-neutral-400 shrink-0 w-14">{item.code}</span>
                        <span className="flex-1 leading-snug">{item.name}</span>
                      </button>
                    ))}
                  </div>
                );
              })
            )}
          </div>
        </div>
      )}
    </div>
  );
}
