/* logicgateslab.jsx — LogicGatesTutor: the single two-input logic-gate bench. Built on
   window.BenchKit (harness) + window.BenchFields (shared field math), so this file is just
   the FIGURE. compute = window.BenchFields.logicGates — the SAME function
   server/benches/logicgates.js calls, so client and server fields are identical by
   construction. Mirrors the gas-laws lab: controls → BenchFields.fn(state) → report + meters. */
(function () {
  const { useState, useMemo, useEffect } = React;
  const K = window.BenchKit, C = K.C, SVG_BG = K.SVG_BG;
  const TaskStrip = K.TaskStrip, StatMeter = K.StatMeter;
  const compute = (s) => window.BenchFields.logicGates(s);
  const GATES = ['AND', 'OR', 'XOR', 'NAND', 'NOR', 'XNOR'];

  function Toggle({ label, on, set, color }) {
    return (
      <button onClick={set} style={{ flex: 1, padding: "9px 10px", borderRadius: 6, cursor: "pointer",
        background: on ? color : C.panel2, color: on ? "#06251c" : C.mute, fontWeight: on ? 600 : 400,
        border: `1px solid ${on ? color : C.line}`, fontFamily: "monospace", fontSize: 13 }}>
        {label} = {on ? "1" : "0"}
      </button>
    );
  }

  function GateFig({ task, setTask, tasks, report, event, done }) {
    const [A, setA] = useState(false);
    const [B, setB] = useState(false);
    const [gate, setGate] = useState("AND");
    const fld = useMemo(() => compute({ A, B, gate }), [A, B, gate]);
    useEffect(() => { report(fld); }, [A, B, gate]); // eslint-disable-line

    const t = tasks.find((x) => x.id === task) || tasks[0];
    const out = fld.out;
    const onCol = C.teal, offCol = C.faint;
    // gate box geometry
    const BX = 250, BY = 90, BW = 120, BH = 110;
    const ay = BY + 28, by = BY + BH - 28, oy = BY + BH / 2;

    return (
      <>
        <TaskStrip tasks={tasks} cur={task} setCur={setTask} done={done} goal={t && t.goal} />
        <svg viewBox="0 0 600 300" style={{ width: "100%", background: SVG_BG, border: `1px solid ${C.line}`, borderRadius: 8 }}>
          {/* input lines */}
          <line x1={90} y1={ay} x2={BX} y2={ay} stroke={A ? onCol : offCol} strokeWidth="3" />
          <line x1={90} y1={by} x2={BX} y2={by} stroke={B ? onCol : offCol} strokeWidth="3" />
          <circle cx={90} cy={ay} r={9} fill={A ? onCol : SVG_BG} stroke={A ? onCol : offCol} strokeWidth="2" />
          <circle cx={90} cy={by} r={9} fill={B ? onCol : SVG_BG} stroke={B ? onCol : offCol} strokeWidth="2" />
          <text x={66} y={ay + 4} fill={A ? onCol : C.mute} fontSize="12" fontFamily="monospace" textAnchor="end">A {A ? 1 : 0}</text>
          <text x={66} y={by + 4} fill={B ? onCol : C.mute} fontSize="12" fontFamily="monospace" textAnchor="end">B {B ? 1 : 0}</text>
          {/* gate box */}
          <rect x={BX} y={BY} width={BW} height={BH} rx="8" fill={C.panel} stroke={C.blue} strokeWidth="2" />
          <text x={BX + BW / 2} y={oy + 5} textAnchor="middle" fill={C.ink} fontSize="18" fontWeight="600" fontFamily="monospace">{gate}</text>
          {/* output line */}
          <line x1={BX + BW} y1={oy} x2={510} y2={oy} stroke={out ? onCol : offCol} strokeWidth="3" />
          <circle cx={510} cy={oy} r={11} fill={out ? onCol : SVG_BG} stroke={out ? onCol : offCol} strokeWidth="2" />
          <text x={534} y={oy + 5} fill={out ? onCol : C.mute} fontSize="13" fontFamily="monospace">out {out ? 1 : 0}</text>
          <text x={BX + BW / 2} y={BY - 14} textAnchor="middle" fill={C.mute} fontSize="11" fontFamily="monospace">{A ? 1 : 0} {gate} {B ? 1 : 0} = {out ? 1 : 0}</text>
        </svg>
        <div style={{ marginTop: 10, padding: "8px 12px", borderRadius: 6, background: C.panel, border: `1px solid ${C.line}`, color: C.mute, fontSize: 12.5, fontFamily: "monospace" }}>
          {gate} truth table: toggle A and B through 00, 01, 10, 11 to read every output. Currently out = {out ? 1 : 0}.
        </div>
        <div style={{ display: "flex", gap: 8, marginTop: 12 }}>
          <Toggle label="Input A" on={A} set={() => { const v = !A; setA(v); event("toggled", `A = ${v ? 1 : 0}`, { response: `out ${compute({ A: v, B, gate }).out ? 1 : 0}` }, C.blue); }} color={C.blue} />
          <Toggle label="Input B" on={B} set={() => { const v = !B; setB(v); event("toggled", `B = ${v ? 1 : 0}`, { response: `out ${compute({ A, B: v, gate }).out ? 1 : 0}` }, C.blue); }} color={C.blue} />
        </div>
        <div style={{ display: "flex", gap: 6, marginTop: 8, flexWrap: "wrap" }}>
          {GATES.map((g) => (
            <button key={g} onClick={() => { setGate(g); event("selected", `Gate = ${g}`, { response: `out ${compute({ A, B, gate: g }).out ? 1 : 0}` }, C.amber); }}
              style={{ flex: 1, minWidth: 64, padding: "8px 6px", borderRadius: 6, cursor: "pointer", fontFamily: "monospace", fontSize: 13,
                background: gate === g ? C.amber : C.panel2, color: gate === g ? "#241f18" : C.mute, fontWeight: gate === g ? 600 : 400,
                border: `1px solid ${gate === g ? C.amber : C.line}` }}>{g}</button>
          ))}
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 8, marginTop: 12 }}>
          <StatMeter label="output" v={out ? "1" : "0"} color={out ? C.teal : C.faint} />
          <StatMeter label="gate" v={fld.gate} color={C.amber} />
          <StatMeter label="both on" v={fld.bothOn ? "yes" : "no"} color={C.blue} />
          <StatMeter label="inputs differ" v={fld.inputsDiffer ? "yes" : "no"} color={C.crimson} />
        </div>
      </>
    );
  }

  window.LogicGatesTutor = K.makeTutor(GateFig, { moduleLabel: "Logic-gate bench", benchId: "logicgates" });
})();
