// Active Receiving Session — lean. Pick PO → enter received qty per line → close out.
const { useState: useStateRS, useEffect: useEffectRS, useMemo: useMemoRS } = React;

function ReceivingSession({ wo, user, sessionId, onExit, onComplete }) {
  // Find the PO this WO targets
  const initialPo = wo.poId ? window.PURCHASE_ORDERS.find((p) => p.id === wo.poId) : null;
  const [poId, setPoId] = useStateRS(initialPo?.id || null);
  const po = window.PURCHASE_ORDERS.find((p) => p.id === poId);

  // Lines state: receivedQty per line, plus extra lines added via autofill
  const [received, setReceived] = useStateRS(() =>
    (po?.lines || []).map((l) => ({
      sku: l.sku, vendorSku: l.vendorSku, desc: l.desc, ordered: l.ordered,
      previouslyReceived: l.received,
      receivedNow: Math.max(0, l.ordered - l.received), // default to remaining outstanding
    }))
  );
  const [extras, setExtras] = useStateRS([]);
  const [autofill, setAutofill] = useStateRS("");
  const [showAutofill, setShowAutofill] = useStateRS(false);
  const [elapsed, setElapsed] = useStateRS(0);
  const [pauseModal, setPauseModal] = useStateRS(false);
  const [confirmClose, setConfirmClose] = useStateRS(null); // "FULL" | "PARTIAL"

  useEffectRS(() => {
    const t = setInterval(() => setElapsed((e) => e + 1), 1000);
    return () => clearInterval(t);
  }, []);

  function elapsedFmt() {
    const m = Math.floor(elapsed / 60); const s = elapsed % 60;
    return `00:${String(m).padStart(2,"0")}:${String(s).padStart(2,"0")}`;
  }

  // If no PO selected yet, show picker
  if (!po) return <POPicker onPick={setPoId} onExit={onExit} />;

  const allLines = [...received, ...extras];
  const totalUnits = allLines.reduce((s, l) => s + (l.receivedNow || 0), 0);
  const fullyReceived = received.every((l) => l.previouslyReceived + l.receivedNow >= l.ordered);
  const hasShort = received.some((l) => l.previouslyReceived + l.receivedNow < l.ordered);

  // Filter SUPPLIER_SKU_MAP for autofill
  const autofillResults = useMemoRS(() => {
    if (!autofill.trim()) return [];
    const q = autofill.toLowerCase();
    return (window.SUPPLIER_SKU_MAP || []).filter((s) =>
      s.supplierSku.toLowerCase().includes(q) ||
      s.gpsSku.toLowerCase().includes(q) ||
      s.name.toLowerCase().includes(q)
    ).slice(0, 6);
  }, [autofill]);

  function setLineQty(idx, qty, isExtra = false) {
    qty = Math.max(0, qty);
    if (isExtra) {
      setExtras((arr) => arr.map((l, i) => i === idx ? { ...l, receivedNow: qty } : l));
    } else {
      setReceived((arr) => arr.map((l, i) => i === idx ? { ...l, receivedNow: qty } : l));
    }
  }

  function addExtra(s) {
    if (extras.some((e) => e.sku === s.gpsSku)) {
      window.gpsToast && window.gpsToast({ message: `${s.gpsSku} already on the list`, tone: "info" });
      return;
    }
    setExtras((arr) => [...arr, {
      sku: s.gpsSku, vendorSku: s.supplierSku, desc: s.name,
      ordered: 0, previouslyReceived: 0, receivedNow: 1, isExtra: true,
    }]);
    setAutofill("");
    setShowAutofill(false);
  }

  function removeExtra(idx) {
    setExtras((arr) => arr.filter((_, i) => i !== idx));
  }

  async function submitClose(mode) {
    const lines = allLines
      .map((l) => ({ line_id: l.sku, sku: l.sku, qty_received: l.receivedNow || 0 }))
      .filter((l) => l.qty_received > 0);

    if (wo.po_id && lines.length > 0) {
      try {
        await fetch(`/api/purchase-orders/${wo.po_id}/receive`, {
          method: 'PATCH', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ lines }),
        });
      } catch {}
    }
    onComplete({
      poId, mode, totalUnits,
      lines: allLines.map((l) => ({ sku: l.sku, receivedNow: l.receivedNow, ordered: l.ordered })),
    });
  }

  return (
    <div className="min-h-screen bg-zinc-950 text-zinc-100 flex flex-col relative">
      <window.TopStripe />

      <header className="border-b border-zinc-800 bg-zinc-900/40 px-6 h-[64px] flex items-center justify-between flex-shrink-0">
        <div className="flex items-center gap-3">
          <button onClick={() => setPauseModal(true)}
            className="h-10 px-3 rounded-lg bg-amber-500/15 border border-amber-500/40 text-amber-200 text-[13px] font-medium hover:bg-amber-500/25 uppercase tracking-wider flex items-center gap-2">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>
            Pause
          </button>
          <button onClick={onExit}
            className="h-10 px-3 rounded-lg bg-zinc-800 border border-zinc-700 text-zinc-200 text-[13px] font-medium hover:bg-zinc-700 uppercase tracking-wider">
            ← Queue
          </button>
          <span className="font-mono text-[13px] text-zinc-500">{wo.id}</span>
          <span className="px-2 py-1 rounded text-[11px] font-bold uppercase tracking-wider bg-teal-500/10 text-teal-300 border border-teal-500/30">RECEIVING</span>
        </div>
        <div className="flex items-center gap-5 text-[14px]">
          <div className="text-zinc-400">Elapsed <span className="font-mono text-zinc-200">{elapsedFmt()}</span></div>
          <div className="text-zinc-300">{user.name}</div>
        </div>
      </header>

      <div className="flex-1 px-6 py-6 overflow-y-auto">
        <div className="max-w-[1100px] mx-auto space-y-5">
          {/* PO header */}
          <div className="bg-zinc-900 border border-zinc-800 rounded-2xl p-6 flex items-center gap-5 flex-wrap">
            <div className="flex-1 min-w-[300px]">
              <div className="text-[12px] uppercase tracking-[0.22em] text-zinc-500">Receiving inbound</div>
              <div className="font-display text-[36px] tracking-tight leading-tight mt-1">{po.vendor}</div>
              <div className="font-mono text-[14px] text-zinc-400 mt-1">{po.id} · sent {po.sent} · expected {po.expected}</div>
            </div>
            <div className="grid grid-cols-3 gap-3 flex-1 min-w-[280px]">
              <Tile label="Lines" value={po.lines.length} />
              <Tile label="Units this session" value={totalUnits} tone={totalUnits > 0 ? "ok" : "neutral"} />
              <Tile label="Status" value={fullyReceived ? "FULL" : hasShort ? "PARTIAL" : "READY"} tone={fullyReceived ? "ok" : "warn"} small />
            </div>
          </div>

          {/* Line items table */}
          <div className="bg-zinc-900 border border-zinc-800 rounded-2xl overflow-hidden">
            <div className="px-5 py-4 border-b border-zinc-800 flex items-center justify-between">
              <div className="font-display text-[22px] tracking-wider text-zinc-300">LINE ITEMS</div>
              <button onClick={() => setShowAutofill(true)}
                className="h-9 px-3 rounded-lg bg-zinc-800 border border-zinc-700 text-zinc-200 text-[12px] font-display tracking-wider hover:bg-zinc-700">
                + ADD EXTRA LINE
              </button>
            </div>

            <div className="divide-y divide-zinc-800/80">
              {received.map((l, i) => (
                <LineRow key={l.sku} line={l} onChange={(q) => setLineQty(i, q)} />
              ))}
              {extras.map((l, i) => (
                <LineRow key={`x-${l.sku}`} line={l} isExtra onChange={(q) => setLineQty(i, q, true)} onRemove={() => removeExtra(i)} />
              ))}
            </div>

            {/* Autofill row */}
            {showAutofill && (
              <div className="px-5 py-4 border-t border-zinc-800 bg-zinc-950/60">
                <div className="text-[12px] uppercase tracking-wider text-zinc-400 mb-2">Type supplier SKU, GPS SKU, or name</div>
                <input value={autofill} onChange={(e) => setAutofill(e.target.value)} autoFocus
                  placeholder="ARP-3032, GPS-BOLT, bolt grade 10.9 …"
                  className="w-full h-[52px] px-4 bg-zinc-950 border-2 border-zinc-700 rounded-lg text-[16px] outline-none focus:border-zinc-500" />
                {autofillResults.length > 0 && (
                  <div className="mt-2 bg-zinc-900 border border-zinc-800 rounded-lg overflow-hidden divide-y divide-zinc-800/60 max-h-[260px] overflow-y-auto">
                    {autofillResults.map((s) => (
                      <button key={s.supplierSku} onClick={() => addExtra(s)}
                        className="w-full grid grid-cols-[1.2fr_1.4fr_2fr_1fr] items-center px-4 py-2 text-left hover:bg-zinc-800/60 text-[13px]">
                        <div className="font-mono text-zinc-200">{s.supplierSku}</div>
                        <div className="font-mono text-zinc-400">→ {s.gpsSku}</div>
                        <div className="truncate">{s.name}</div>
                        <div className="text-zinc-500 text-right">{s.vendor}</div>
                      </button>
                    ))}
                  </div>
                )}
                {autofill && autofillResults.length === 0 && (
                  <div className="text-[13px] text-zinc-500 mt-2">No matches — try a different search.</div>
                )}
                <div className="flex justify-end mt-2">
                  <button onClick={() => { setShowAutofill(false); setAutofill(""); }}
                    className="h-8 px-3 rounded text-zinc-400 text-[12px] uppercase tracking-wider hover:bg-zinc-800">Cancel</button>
                </div>
              </div>
            )}
          </div>

          {/* Close out */}
          <div className="grid grid-cols-2 gap-3">
            <window.HoldButton color="amber" holdMs={500}
              onComplete={() => submitClose("PARTIAL")}
              disabled={totalUnits === 0}
              className="h-[100px]"
              subText="some lines still outstanding · stay open">
              <div className="font-display text-[24px] tracking-wider">CLOSE PARTIAL</div>
            </window.HoldButton>
            <window.HoldButton color="emerald" holdMs={500}
              onComplete={() => submitClose("FULL")}
              disabled={totalUnits === 0}
              className="h-[100px]"
              subText="all lines received · PO complete">
              <div className="font-display text-[24px] tracking-wider">✓ CLOSE OUT · FULL</div>
            </window.HoldButton>
          </div>
        </div>
      </div>

      {pauseModal && (
        <window.PauseModal
          context={`Receiving · PO ${po.id} · ${totalUnits} units logged so far`}
          onCancel={() => setPauseModal(false)}
          onPause={async (payload) => {
            setPauseModal(false);
            if (sessionId) {
              try {
                await fetch(`/api/sessions/${sessionId}`, {
                  method: 'PATCH', headers: { 'Content-Type': 'application/json' },
                  body: JSON.stringify({
                    status: 'paused',
                    pause_reason: payload?.reason || '',
                    pause_note: payload?.note || '',
                    state: { poId, received, extras },
                  }),
                });
              } catch {}
            }
            onExit();
          }}
          onMaterialResolved={() => setPauseModal(false)}
        />
      )}
    </div>
  );
}

function LineRow({ line, isExtra, onChange, onRemove }) {
  const outstanding = Math.max(0, line.ordered - line.previouslyReceived);
  const willBeReceived = line.previouslyReceived + line.receivedNow;
  const fullyDone = !isExtra && willBeReceived >= line.ordered;
  const over = !isExtra && willBeReceived > line.ordered;

  return (
    <div className="grid grid-cols-[1.4fr_2fr_0.8fr_1.4fr_0.6fr] items-center gap-3 px-5 py-3">
      <div>
        <div className="font-mono text-[12px] text-zinc-500">{line.vendorSku}</div>
        <div className="font-mono text-[13px] text-zinc-200">→ {line.sku}</div>
      </div>
      <div className="text-[14px] truncate">{line.desc}</div>
      <div className="text-right">
        {!isExtra && (
          <>
            <div className="font-display text-[20px] tabular-nums">{line.ordered}</div>
            <div className="text-[11px] text-zinc-500 uppercase tracking-wider">ordered</div>
            {line.previouslyReceived > 0 && (
              <div className="text-[11px] text-zinc-400 mt-0.5">{line.previouslyReceived} prev</div>
            )}
          </>
        )}
        {isExtra && (
          <span className="px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-wider border bg-amber-500/10 text-amber-300 border-amber-500/30">
            EXTRA
          </span>
        )}
      </div>
      <div>
        <div className="text-[11px] uppercase tracking-wider text-zinc-400 mb-1">Received now</div>
        <div className="flex items-center gap-1.5">
          <button onClick={() => onChange(line.receivedNow - 1)}
            className="h-[44px] w-[44px] rounded-lg bg-zinc-800 border border-zinc-700 text-[18px] font-display">−</button>
          <input type="number" value={line.receivedNow}
            onChange={(e) => onChange(parseInt(e.target.value || "0", 10))}
            className={`h-[52px] flex-1 min-w-0 bg-zinc-950 border-2 rounded-lg text-center font-display text-[24px] tabular-nums outline-none focus:border-zinc-500 ${
              fullyDone ? "border-emerald-500/50" : over ? "border-amber-500/50" : "border-zinc-800"
            }`} />
          <button onClick={() => onChange(line.receivedNow + 1)}
            className="h-[44px] w-[44px] rounded-lg bg-zinc-800 border border-zinc-700 text-[18px] font-display">+</button>
          {!isExtra && outstanding > 0 && line.receivedNow !== outstanding && (
            <button onClick={() => onChange(outstanding)}
              className="h-[44px] px-2 rounded-lg bg-zinc-800 border border-zinc-700 text-[11px] uppercase tracking-wider text-zinc-300 hover:bg-zinc-700 whitespace-nowrap">
              All {outstanding}
            </button>
          )}
        </div>
      </div>
      <div className="flex justify-end">
        {isExtra ? (
          <button onClick={onRemove}
            className="h-8 w-8 rounded text-zinc-400 hover:bg-red-500/20 hover:text-red-300 flex items-center justify-center">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
          </button>
        ) : fullyDone ? (
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#10b981" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
        ) : over ? (
          <span className="text-amber-400 text-[18px]">!</span>
        ) : null}
      </div>
    </div>
  );
}

function POPicker({ onPick, onExit }) {
  const openPOs = (window.PURCHASE_ORDERS || []).filter((p) => p.status !== "RECEIVED");
  return (
    <div className="min-h-screen bg-zinc-950 text-zinc-100 flex flex-col relative">
      <window.TopStripe />
      <header className="border-b border-zinc-800 bg-zinc-900/40 px-6 py-4 flex items-center justify-between">
        <button onClick={onExit}
          className="h-10 px-3 rounded-lg bg-zinc-800 border border-zinc-700 text-zinc-200 text-[13px] font-medium hover:bg-zinc-700 uppercase tracking-wider">
          ← Back to queue
        </button>
        <span className="px-2 py-1 rounded text-[11px] font-bold uppercase tracking-wider bg-teal-500/10 text-teal-300 border border-teal-500/30">RECEIVING</span>
        <div className="w-[100px]" />
      </header>
      <div className="flex-1 flex items-center justify-center px-6 py-10 overflow-y-auto">
        <div className="w-full max-w-[820px]">
          <div className="text-center mb-8">
            <div className="text-[13px] uppercase tracking-[0.22em] text-zinc-500">Receiving inbound shipment</div>
            <div className="font-display text-[44px] leading-[1.0] tracking-tight mt-2">Which PO?</div>
            <div className="text-[15px] text-zinc-400 mt-2">Pick the PO that matches the packing slip in front of you.</div>
          </div>
          <div className="space-y-2">
            {openPOs.map((p) => (
              <button key={p.id} onClick={() => onPick(p.id)}
                className="w-full bg-zinc-900 border border-zinc-800 hover:border-zinc-600 hover:bg-zinc-800/40 rounded-xl p-4 text-left flex items-center gap-4 transition">
                <div className="flex-1 min-w-0">
                  <div className="font-mono text-[12px] text-zinc-500">{p.id}</div>
                  <div className="font-display text-[22px] tracking-tight">{p.vendor}</div>
                  <div className="text-[12px] text-zinc-400 mt-0.5">{p.lines.length} line{p.lines.length > 1 ? "s" : ""} · sent {p.sent} · expected {p.expected}</div>
                </div>
                <div className={`px-2.5 py-1 rounded text-[11px] font-bold tracking-wider uppercase border ${p.status === "SENT" ? "text-sky-200 bg-sky-500/15 border-sky-500/40" : "text-amber-200 bg-amber-500/15 border-amber-500/40"}`}>
                  {p.status}
                </div>
              </button>
            ))}
            {openPOs.length === 0 && (
              <div className="text-center text-zinc-500 py-12">No open POs to receive against.</div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function Tile({ label, value, tone = "neutral", small = false }) {
  const color =
    tone === "warn" ? "text-amber-400" :
    tone === "ok" ? "text-emerald-400" :
    "text-zinc-100";
  return (
    <div className="bg-zinc-950/60 border border-zinc-800 rounded-lg px-3 py-2">
      <div className="text-[10px] uppercase tracking-wider text-zinc-500">{label}</div>
      <div className={`font-display tabular-nums leading-none mt-1 ${color} ${small ? "text-[20px] mt-2" : "text-[28px]"}`}>{value}</div>
    </div>
  );
}

window.ReceivingSession = ReceivingSession;
