/* periodictrendslab.jsx — PeriodicTrendsTutor: the periodic-trends bench. Built on
   window.BenchKit (harness) + window.BenchFields (shared field math), so this file is just
   the FIGURE. compute = window.BenchFields.periodicTrends — the SAME function
   server/benches/periodictrends.js calls, so client and server fields are identical by
   construction. The learner picks a PERIOD (row) and a MAIN GROUP (column); Zeff, atomic
   radius and ionization energy update live, illustrating the periodic trends. */
(function () {
  const { useState, useMemo, useEffect } = React;
  const K = window.BenchKit, C = K.C, SVG_BG = K.SVG_BG, fmt = K.fmt;
  const TaskStrip = K.TaskStrip, StatMeter = K.StatMeter;
  const compute = (s) => window.BenchFields.periodicTrends(s);

  function Slider({ label, value, set, min, max, step, unit, color, onUp }) {
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 9 }}>
        <span style={{ fontSize: 12, color: C.mute, width: 116 }}>{label}</span>
        <input type="range" min={min} max={max} step={step} value={value} onChange={(e) => set(parseFloat(e.target.value))} onPointerUp={onUp} style={{ flex: 1 }} />
        <span style={{ color: color || C.amber, width: 64, textAlign: "right" }}>{value}{unit ? ` ${unit}` : ""}</span>
      </div>
    );
  }

  function PeriodicTrendsFig({ task, setTask, tasks, report, event, done }) {
    const [period, setPeriod] = useState(3);
    const [group, setGroup] = useState(1);
    const fld = useMemo(() => compute({ period, group }), [period, group]);
    useEffect(() => { report(fld); }, [period, group]); // eslint-disable-line

    // 7 rows × 8 main-group columns grid; selected cell highlighted.
    const ROWS = 7, COLS = 8;
    const GX0 = 70, GY0 = 64, CELL = 30;
    const cellX = (g) => GX0 + (g - 1) * CELL;     // g: 1..8 (column)
    const cellY = (p) => GY0 + (p - 1) * CELL;     // p: 1..7 (row)
    const selX = cellX(group), selY = cellY(period);

    // atom glyph whose drawn radius ∝ atomicRadius (clamped to a sensible pixel range).
    const ACX = 470, ACY = 150;
    const rPix = Math.max(8, Math.min(70, 8 + (fld.atomicRadius / 227) * 62));
    const heat = Math.min(1, Math.max(0, fld.zEff / 8));

    const t = tasks.find((x) => x.id === task) || tasks[0];
    const cells = [];
    for (let p = 1; p <= ROWS; p++) for (let g = 1; g <= COLS; g++) cells.push({ p, g });

    return (
      <>
        <TaskStrip tasks={tasks} cur={task} setCur={setTask} done={done} goal={t && t.goal} />
        <svg viewBox="0 0 600 320" style={{ width: "100%", background: SVG_BG, border: `1px solid ${C.line}`, borderRadius: 8 }}>
          {/* period × group grid */}
          {cells.map(({ p, g }) => (
            <rect key={`${p}-${g}`} x={cellX(g)} y={cellY(p)} width={CELL - 2} height={CELL - 2}
              fill={p === period && g === group ? C.gold : C.panel} opacity={p === period && g === group ? 0.9 : 0.5}
              stroke={C.faint} strokeWidth="1" rx="3" />
          ))}
          <text x={selX + (CELL - 2) / 2} y={selY + (CELL - 2) / 2 + 4} textAnchor="middle" fill={C.bg} fontSize="11" fontFamily="monospace" fontWeight="bold">{group}</text>
          {/* axis labels */}
          <text x={GX0} y={GY0 - 10} fill={C.mute} fontSize="11" fontFamily="monospace">group 1 → 8 (across a period)</text>
          <text x={GX0 - 8} y={GY0 + ROWS * CELL + 16} fill={C.mute} fontSize="11" fontFamily="monospace">period 1 → 7 (down)</text>
          {/* trend arrows along the edges */}
          <line x1={GX0} y1={GY0 - 24} x2={GX0 + COLS * CELL - 6} y2={GY0 - 24} stroke={C.crimson} strokeWidth="2" markerEnd="url(#arrR)" />
          <text x={GX0 + COLS * CELL / 2} y={GY0 - 28} textAnchor="middle" fill={C.crimson} fontSize="10" fontFamily="monospace">Zeff ↑ · radius ↓ · ionization ↑</text>
          <line x1={GX0 - 24} y1={GY0} x2={GX0 - 24} y2={GY0 + ROWS * CELL - 6} stroke={C.blue} strokeWidth="2" markerEnd="url(#arrD)" />
          <defs>
            <marker id="arrR" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill={C.crimson} /></marker>
            <marker id="arrD" markerWidth="8" markerHeight="8" refX="3" refY="6" orient="auto"><path d="M0,0 L3,6 L6,0 Z" fill={C.blue} /></marker>
          </defs>
          {/* atom glyph: drawn radius ∝ atomicRadius */}
          <circle cx={ACX} cy={ACY} r={rPix} fill={C.teal} opacity={0.18 + heat * 0.18} />
          <circle cx={ACX} cy={ACY} r={rPix} fill="none" stroke={C.teal} strokeWidth="1.5" />
          <circle cx={ACX} cy={ACY} r={6} fill={heat > 0.7 ? C.crimson : C.gold} />
          <text x={ACX} y={ACY - rPix - 8} textAnchor="middle" fill={C.mute} fontSize="11" fontFamily="monospace">radius ≈ {fmt(fld.atomicRadius)}</text>
          {/* live labels for Zeff and ionization energy */}
          <text x={ACX} y={ACY + rPix + 18} textAnchor="middle" fill={C.ink} fontSize="12" fontFamily="monospace">Zeff = {fmt(fld.zEff)}</text>
          <text x={ACX} y={ACY + rPix + 34} textAnchor="middle" fill={C.amber} fontSize="12" fontFamily="monospace">IE ≈ {fmt(fld.ionizationE)}</text>
          {fld.smallRadius ? <text x={ACX} y={ACY + rPix + 50} textAnchor="middle" fill={C.crimson} fontSize="11" fontFamily="monospace">small-atom corner</text> : null}
        </svg>
        <div style={{ marginTop: 10, padding: "8px 12px", borderRadius: 6, background: C.panel, border: `1px solid ${C.line}`, color: C.mute, fontSize: 12.5 }}>
          Across a period Zeff ↑ so radius ↓ and ionization ↑; down a group a new shell is added so radius ↑ and ionization ↓. {fld.smallRadius ? "You are in the small, hard-to-ionize corner (top-right)." : "Step toward the top-right for small atoms, bottom-left for large atoms."}
        </div>
        <Slider label="period (row)" value={period} set={setPeriod} min={1} max={7} step={1} color={C.blue} onUp={() => event("adjusted", `Set period = ${period}`, { response: `radius ${fmt(fld.atomicRadius)} · IE ${fmt(fld.ionizationE)}` }, C.blue)} />
        <Slider label="main group (col)" value={group} set={setGroup} min={1} max={8} step={1} color={C.crimson} onUp={() => event("adjusted", `Set group = ${group}`, { response: `Zeff ${fmt(fld.zEff)} · IE ${fmt(fld.ionizationE)}` }, C.crimson)} />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 8, marginTop: 12 }}>
          <StatMeter label="Zeff" v={fld.zEff} color={fld.zEff >= 7 ? C.crimson : C.teal} />
          <StatMeter label="atomic radius" v={fld.atomicRadius} color={C.teal} />
          <StatMeter label="ionization E" v={fld.ionizationE} d={0} color={C.amber} />
          <StatMeter label="group" v={fld.group} d={0} color={C.blue} />
        </div>
      </>
    );
  }

  window.PeriodicTrendsTutor = K.makeTutor(PeriodicTrendsFig, { moduleLabel: "Periodic trends bench", benchId: "periodictrends" });
})();
