'use client';

import { useEffect, useRef, useState } from 'react';

export interface ComboboxItem {
  id: number;
  label: string;
  subtitle?: string;
}

interface Props {
  value: number | null;
  items: ComboboxItem[];
  onChange: (id: number | null, item: ComboboxItem | null) => void;
  /**
   * Fired when the user clicks "+ Add new" or presses Enter on a query that
   * has no exact match. The host owns the actual add-new flow and is expected
   * to call onChange(newId, newItem) once the row is created.
   */
  onAddNew?: (query: string) => void;
  placeholder?: string;
  emptyHint?: string;
  className?: string;
}

// Searchable combobox with optional "+ Add new" affordance. Filters items
// client-side by case-insensitive substring on label.
export function ComboboxAddNew({
  value,
  items,
  onChange,
  onAddNew,
  placeholder = 'Search…',
  emptyHint = 'No matches',
  className = '',
}: Props) {
  const [open, setOpen] = useState(false);
  const [q, setQ] = useState('');
  const wrapRef = useRef<HTMLDivElement | null>(null);

  const selected = value !== null ? items.find((it) => it.id === value) ?? null : null;

  // Close on outside click
  useEffect(() => {
    if (!open) return;
    function onDocClick(e: MouseEvent) {
      if (wrapRef.current && !wrapRef.current.contains(e.target as Node)) {
        setOpen(false);
      }
    }
    document.addEventListener('mousedown', onDocClick);
    return () => document.removeEventListener('mousedown', onDocClick);
  }, [open]);

  const ql = q.trim().toLowerCase();
  const filtered = ql
    ? items.filter((it) => it.label.toLowerCase().includes(ql))
    : items;
  const exactMatch = ql ? items.some((it) => it.label.toLowerCase() === ql) : false;

  function pick(item: ComboboxItem) {
    onChange(item.id, item);
    setQ('');
    setOpen(false);
  }

  function clear() {
    onChange(null, null);
    setQ('');
  }

  return (
    <div ref={wrapRef} className={`relative ${className}`}>
      {/* Trigger / display */}
      {selected && !open ? (
        <div className="flex items-center justify-between rounded-md border border-paper-300 bg-white px-3 py-2 text-sm">
          <button
            type="button"
            onClick={() => setOpen(true)}
            className="flex-1 text-left text-ink"
          >
            <span className="block truncate">{selected.label}</span>
            {selected.subtitle && (
              <span className="block truncate text-xs text-ink-300">{selected.subtitle}</span>
            )}
          </button>
          <button
            type="button"
            onClick={clear}
            aria-label="Clear selection"
            className="ml-2 text-ink-300 hover:text-ink"
          >
            ×
          </button>
        </div>
      ) : (
        <input
          type="text"
          value={q}
          onChange={(e) => setQ(e.target.value)}
          onFocus={() => setOpen(true)}
          placeholder={placeholder}
          className="w-full rounded-md border border-paper-300 bg-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-saffron"
        />
      )}

      {/* Popover */}
      {open && (
        <div className="absolute left-0 right-0 z-30 mt-1 max-h-64 overflow-y-auto rounded-md border border-paper-200 bg-white shadow-lg">
          {filtered.length === 0 ? (
            <div className="px-3 py-2 text-xs text-ink-300">{emptyHint}</div>
          ) : (
            filtered.map((it) => (
              <button
                key={it.id}
                type="button"
                onClick={() => pick(it)}
                className={`flex w-full flex-col items-start px-3 py-2 text-left text-sm hover:bg-paper-50 ${
                  it.id === value ? 'bg-saffron/10' : ''
                }`}
              >
                <span className="text-ink">{it.label}</span>
                {it.subtitle && <span className="text-xs text-ink-300">{it.subtitle}</span>}
              </button>
            ))
          )}

          {onAddNew && ql && !exactMatch && (
            <button
              type="button"
              onClick={() => {
                onAddNew(q.trim());
                setOpen(false);
              }}
              className="flex w-full items-center gap-2 border-t border-paper-200 bg-paper-50 px-3 py-2 text-left text-sm text-saffron-700 hover:bg-paper-100"
            >
              <span className="text-base leading-none">+</span>
              <span>
                Add &quot;<strong>{q.trim()}</strong>&quot;
              </span>
            </button>
          )}
        </div>
      )}
    </div>
  );
}
