/* parametriclab.jsx — ParametricTutor: the parametric-curves bench. Built on
   window.BenchKit (harness) + window.BenchFields (shared field math), so this file is just the
   FIGURE. computeFields = window.BenchFields.parametric — the SAME function
   server/benches/parametric.js calls, so client and server fields are identical by construction.
   The learner sets the x-amplitude A, the y-frequency m and the parameter t; the full curve
   x = A·cos t, y = sin(m t) is traced as a polyline, the point at parameter t is a dot, and the
   velocity (dx/dt, dy/dt) is an arrow tangent to the curve. The tangent slope dy/dx and speed
   update live; horizontal tangents appear where dy/dt = 0, vertical where dx/dt = 0. */
(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.parametric(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 }}><K.T>{label}</K.T></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 ParametricFig({ task, setTask, tasks, report, event, done }) {
    const [A, setA] = useState(2);
    const [m, setM] = useState(2);
    const [t, setT] = useState(45);
    const fld = useMemo(() => compute({ A, m, t }), [A, m, t]);
    useEffect(() => { report(fld); }, [A, m, t]); // eslint-disable-line

    // plot: centred axes; map (x in [-A,A], y in [-1,1]) into the SVG.
    const CX = 200, CY = 150;                      // centre of the plot
    const sx = 150 / Math.max(1, A);               // px per x-unit (A up to 3)
    const sy = 110;                                // px per y-unit (|y| ≤ 1)
    const px = (x) => CX + x * sx;
    const py = (y) => CY - y * sy;

    // trace the full curve t = 0..360 as a polyline.
    const pts = [];
    for (let d = 0; d <= 360; d += 4) {
      const f = compute({ A, m, t: d });
      pts.push(`${px(f.x).toFixed(1)},${py(f.y).toFixed(1)}`);
    }
    const path = pts.join(" ");

    // velocity / tangent arrow from the current point, scaled to a readable length.
    const vmag = Math.max(0.001, fld.speed);
    const aLen = 46;                               // arrow length in px
    const ux = fld.dxdt / vmag, uy = fld.dydt / vmag;
    const hx = px(fld.x), hy = py(fld.y);
    const tx = hx + ux * aLen, ty = hy - uy * aLen; // note: screen-y is inverted
    const ang = Math.atan2(-(ty - hy), tx - hx);
    const head = (a) => `${(tx - 8 * Math.cos(ang - a)).toFixed(1)},${(ty + 8 * Math.sin(ang - a)).toFixed(1)}`;

    const tk = tasks.find((x) => x.id === task) || tasks[0];
    const horiz = Math.abs(fld.dydt) < 0.1;
    const vert = Math.abs(fld.dxdt) < 0.1;
    const okColor = (horiz || vert) ? C.teal : C.amber;
    const note = vert ? "Vertical tangent — dx/dt ≈ 0, the slope dy/dx is undefined."
      : horiz ? "Horizontal tangent — dy/dt ≈ 0, the slope dy/dx ≈ 0."
        : "Tracing the curve — the arrow is the velocity, tangent to the curve.";

    return (
      <>
        <TaskStrip tasks={tasks} cur={task} setCur={setTask} done={done} goal={tk && tk.goal} />
        <svg viewBox="0 0 600 300" style={{ width: "100%", background: SVG_BG, border: `1px solid ${C.line}`, borderRadius: 8 }}>
          {/* centred axes */}
          <line x1={px(-A)} y1={CY} x2={px(A)} y2={CY} stroke={C.faint} strokeWidth="1" />
          <line x1={CX} y1={py(-1)} x2={CX} y2={py(1)} stroke={C.faint} strokeWidth="1" />
          {/* the traced parametric curve */}
          <polyline points={path} fill="none" stroke={C.gold} strokeWidth="2" />
          {/* the current point */}
          <circle cx={hx} cy={hy} r="5" fill={C.blue} stroke={C.line} strokeWidth="0.8" />
          {/* the velocity / tangent vector */}
          <line x1={hx} y1={hy} x2={tx} y2={ty} stroke={okColor} strokeWidth="2.2" />
          <polygon points={`${tx.toFixed(1)},${ty.toFixed(1)} ${head(0.45)} ${head(-0.45)}`} fill={okColor} />
          {/* readout panel on the right */}
          <text x={420} y={40} fill={C.mute} fontSize="12" fontFamily="monospace">x = A·cos t, y = sin(m t)</text>
          <text x={420} y={66} fill={C.blue} fontSize="13" fontFamily="monospace">point ({fmt(fld.x)}, {fmt(fld.y)})</text>
          <text x={420} y={88} fill={C.teal} fontSize="13" fontFamily="monospace">vel ({fmt(fld.dxdt)}, {fmt(fld.dydt)})</text>
          <text x={420} y={110} fill={okColor} fontSize="13" fontFamily="monospace">slope = {vert ? "undef" : fmt(fld.slope)}</text>
          <text x={420} y={132} fill={C.mute} fontSize="12" fontFamily="monospace">speed = {fmt(fld.speed)}</text>
          <text x={420} y={154} fill={C.faint} fontSize="11" fontFamily="monospace">t = {fmt(t)}°</text>
        </svg>
        <div style={{ marginTop: 10, padding: "8px 12px", borderRadius: 6, background: C.panel, border: `1px solid ${(horiz || vert) ? C.teal : C.line}`, color: (horiz || vert) ? C.teal : C.mute, fontSize: 12.5 }}>
          {(horiz || vert) ? <>⚑ <K.T>{note}</K.T></> : <K.T>{note}</K.T>}
        </div>
        <Slider label="x-amplitude A" value={A} set={setA} min={1} max={3} step={0.5} unit="" color={C.gold} onUp={() => event("adjusted", `Set A = ${fmt(A)}`, { response: `speed ${fmt(fld.speed)}` }, C.gold)} />
        <Slider label="y-frequency m" value={m} set={(v) => setM(Math.round(v))} min={1} max={3} step={1} unit="" color={C.teal} onUp={() => event("adjusted", `Set m = ${fmt(Math.round(m))}`, { response: `speed ${fmt(fld.speed)}` }, C.teal)} />
        <Slider label="parameter t" value={t} set={setT} min={0} max={360} step={5} unit="°" color={C.blue} onUp={() => event("adjusted", `Set t = ${fmt(t)}°`, { response: `slope ${fmt(fld.slope)}` }, C.blue)} />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 8, marginTop: 12 }}>
          <StatMeter label="dx/dt" v={fld.dxdt} d={2} color={C.teal} />
          <StatMeter label="dy/dt" v={fld.dydt} d={2} color={C.gold} />
          <StatMeter label="speed" v={fld.speed} d={2} color={C.blue} />
          <StatMeter label="slope dy/dx" v={fld.slope} d={2} color={okColor} />
        </div>
      </>
    );
  }

  window.ParametricTutor = K.makeTutor(ParametricFig, { moduleLabel: "Parametric Curves bench", benchId: "parametric" });
})();
