"use client";

/**
 * ItemCodeInput — keyboard-first item entry for staff order creation.
 *
 * Flow (all keyboard):
 *   1. Type code or name fragment  → fuzzy dropdown appears
 *   2. ↑/↓ to highlight, Enter/Tab to select  → jumps to Qty
 *   3. Type qty (default 1, ↑/↓ to change) → Enter → jumps to Note
 *   4. Type note (optional) → Enter → item added → focus back to code
 *
 * Pressing Enter on an EMPTY code field when cart has items signals "done".
 * Escape at any point resets back to code field.
 */

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

import { Check, Plus } from "lucide-react";

import { MOCK_MENU, type MenuItem } from "@/lib/order/mock-menu";
import type { OrderItem } from "@/lib/order/types";

interface ItemCodeInputProps {
  /** Called when an item row is confirmed (code + qty + notes). */
  onAdd: (item: OrderItem) => void;
  /** Called when Enter pressed on empty code with cartSize > 0 — signals "done adding". */
  onDone?: () => void;
  cartSize?: number;
  autoFocus?: boolean;
}

type Field = "code" | "qty" | "notes";

function fuzzySearch(query: string): MenuItem[] {
  const q = query.trim().toLowerCase();
  if (!q) return [];
  return MOCK_MENU.map((item) => {
    const code = item.code.toLowerCase();
    const desc = item.description.toLowerCase();
    let score = 0;
    if (code === q)              score = 100;
    else if (code.startsWith(q)) score = 80;
    else if (desc.startsWith(q)) score = 60;
    else if (code.includes(q))   score = 40;
    else if (desc.includes(q))   score = 20;
    return { item, score };
  })
    .filter((r) => r.score > 0)
    .sort((a, b) => b.score - a.score)
    .map((r) => r.item)
    .slice(0, 8);
}

export function ItemCodeInput({ onAdd, onDone, cartSize = 0, autoFocus = false }: ItemCodeInputProps) {
  const [field, setField] = useState<Field>("code");
  const [code, setCode]   = useState("");
  const [results, setResults] = useState<MenuItem[]>([]);
  const [highlighted, setHighlighted] = useState(0);
  const [selected, setSelected] = useState<MenuItem | null>(null);
  const [qty, setQty]     = useState(1);
  const [notes, setNotes] = useState("");

  const codeRef  = useRef<HTMLInputElement>(null);
  const qtyRef   = useRef<HTMLInputElement>(null);
  const notesRef = useRef<HTMLInputElement>(null);

  // Auto-focus on mount
  useEffect(() => {
    if (autoFocus) codeRef.current?.focus();
  }, [autoFocus]);

  // Re-focus when field changes
  useEffect(() => {
    if (field === "code")  setTimeout(() => codeRef.current?.focus(),  20);
    if (field === "qty")   setTimeout(() => { qtyRef.current?.focus(); qtyRef.current?.select(); }, 20);
    if (field === "notes") setTimeout(() => notesRef.current?.focus(), 20);
  }, [field]);

  const reset = () => {
    setCode(""); setResults([]); setHighlighted(0);
    setSelected(null); setQty(1); setNotes("");
    setField("code");
  };

  const selectItem = (item: MenuItem) => {
    setSelected(item);
    setCode(item.code);
    setResults([]);
    setQty(1);
    setField("qty");
  };

  const confirmAdd = () => {
    if (!selected) return;
    onAdd({ code: selected.code, description: selected.description, chineseName: selected.chineseName, unitPrice: selected.unitPrice, qty, notes: notes.trim() || undefined });
    reset();
  };

  // ── Code field keyboard handling ──────────────────────────────────────────
  const handleCodeKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Escape") { reset(); return; }
    if (results.length > 0) {
      if (e.key === "ArrowDown") { e.preventDefault(); setHighlighted((h) => Math.min(h + 1, results.length - 1)); return; }
      if (e.key === "ArrowUp")   { e.preventDefault(); setHighlighted((h) => Math.max(h - 1, 0)); return; }
      if (e.key === "Enter" || e.key === "Tab") {
        e.preventDefault();
        selectItem(results[highlighted]);
        return;
      }
    }
    if ((e.key === "Enter" || e.key === "Tab") && code.trim() === "" && cartSize > 0) {
      e.preventDefault();
      onDone?.();
    }
  };

  const handleCodeChange = (val: string) => {
    setCode(val);
    setSelected(null);
    const matches = fuzzySearch(val);
    setResults(matches);
    setHighlighted(0);
    // Auto-select if exact code match
    if (matches.length === 1 && matches[0].code.toLowerCase() === val.trim().toLowerCase()) {
      selectItem(matches[0]);
    }
  };

  // ── Qty keyboard handling ─────────────────────────────────────────────────
  const handleQtyKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Escape") { reset(); return; }
    if (e.key === "ArrowUp")   { e.preventDefault(); setQty((q) => q + 1); return; }
    if (e.key === "ArrowDown") { e.preventDefault(); setQty((q) => Math.max(1, q - 1)); return; }
    if (e.key === "Enter" || e.key === "Tab") { e.preventDefault(); setField("notes"); }
  };

  // ── Notes keyboard handling ───────────────────────────────────────────────
  const handleNotesKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Escape") { reset(); return; }
    if (e.key === "Enter") { e.preventDefault(); confirmAdd(); }
    if (e.key === "Tab")   { e.preventDefault(); confirmAdd(); }
  };

  const isActive = !!selected || results.length > 0;

  return (
    <div className={`rounded-lg border-2 transition-colors ${isActive ? "border-primary/50 bg-primary/5" : "border-dashed border-muted-foreground/30 bg-muted/10"}`}>
      {/* Code + results dropdown */}
      <div>
        <div className="flex items-center gap-2 px-3 py-2">
          <span className="w-14 shrink-0 font-mono text-[11px] text-muted-foreground font-semibold">
            {field === "code" ? "code:" : field === "qty" ? "qty:" : "note:"}
          </span>

          {/* Code field */}
          {field === "code" && (
            <input
              ref={codeRef}
              type="text"
              value={code}
              onChange={(e) => handleCodeChange(e.target.value)}
              onKeyDown={handleCodeKey}
              placeholder={cartSize > 0 ? "code or name… (Enter when done)" : "type code or item name…"}
              className="flex-1 bg-transparent text-[13px] outline-none placeholder:text-muted-foreground/50 font-mono"
            />
          )}

          {/* Selected item label + qty field */}
          {field === "qty" && selected && (
            <>
              <span className="flex-1 truncate text-[13px] font-semibold text-primary">{selected.description}</span>
              <span className="text-[12px] text-muted-foreground shrink-0">£{selected.unitPrice.toFixed(2)}</span>
              <span className="text-muted-foreground text-[11px] shrink-0 ml-1">×</span>
              <input
                ref={qtyRef}
                type="number"
                min={1}
                max={99}
                value={qty}
                onChange={(e) => setQty(Math.max(1, parseInt(e.target.value) || 1))}
                onKeyDown={handleQtyKey}
                className="w-12 rounded border bg-background px-1.5 py-0.5 text-center text-[13px] font-bold tabular-nums outline-none focus:border-primary"
              />
            </>
          )}

          {/* Notes field */}
          {field === "notes" && selected && (
            <>
              <span className="shrink-0 font-semibold text-[13px] text-primary mr-1">{selected.description} ×{qty}</span>
              <input
                ref={notesRef}
                type="text"
                value={notes}
                onChange={(e) => setNotes(e.target.value)}
                onKeyDown={handleNotesKey}
                placeholder="note (Enter to add)…"
                className="flex-1 bg-transparent text-[13px] outline-none placeholder:text-muted-foreground/50"
              />
            </>
          )}

          {/* Add button (mouse fallback) */}
          {field === "notes" && (
            <button
              type="button"
              onClick={confirmAdd}
              className="shrink-0 rounded bg-primary px-2.5 py-1 text-[11px] font-bold text-primary-foreground hover:bg-primary/90 flex items-center gap-1"
            >
              <Plus className="size-3" /> Add
            </button>
          )}
          {field === "qty" && (
            <button
              type="button"
              onClick={() => setField("notes")}
              className="shrink-0 rounded border px-2 py-0.5 text-[11px] text-muted-foreground hover:text-foreground"
            >
              →
            </button>
          )}
        </div>

        {/* Fuzzy results dropdown */}
        {results.length > 0 && field === "code" && (
          <div className="border-t bg-popover shadow-sm">
            {results.map((item, i) => (
              <button
                key={item.code}
                type="button"
                onMouseDown={(e) => { e.preventDefault(); selectItem(item); }}
                className={`flex w-full items-center gap-3 px-3 py-2 text-left text-[12px] transition-colors ${
                  i === highlighted ? "bg-primary/10 text-primary" : "hover:bg-muted/50"
                }`}
              >
                <span className="w-8 shrink-0 font-mono font-bold text-primary">{item.code}</span>
                <span className="flex-1 font-medium">{item.description}</span>
                <span className="text-muted-foreground shrink-0">{item.chineseName}</span>
                <span className="tabular-nums font-mono shrink-0">£{item.unitPrice.toFixed(2)}</span>
              </button>
            ))}
          </div>
        )}
      </div>

      {/* Keyboard hints */}
      <div className="px-3 pb-2 flex items-center gap-3 text-[10px] text-muted-foreground/60">
        {field === "code" && results.length > 0 && <span>↑↓ navigate · Enter select</span>}
        {field === "code" && results.length === 0 && code === "" && cartSize > 0 && (
          <span className="flex items-center gap-1 text-green-600/70"><Check className="size-2.5" /> Enter with empty field → done</span>
        )}
        {field === "qty"   && <span>↑↓ change qty · Enter → note</span>}
        {field === "notes" && <span>Enter to add item · Esc to cancel</span>}
      </div>
    </div>
  );
}
