/* polarlab.jsx — PolarTutor: the polar curves & area bench. Built on window.BenchKit
   (harness) + window.BenchFields (shared field math), so this file is just the FIGURE.
   computeFields = window.BenchFields.polar — the SAME function server/benches/polar.js calls,
   so client and server fields are identical by construction. The learner sets the cardioid
   size a, the sweep θmax and the number of sectors n; the cardioid r = a(1+cosθ) is drawn in
   polar axes with the swept region (θ = 0 → θmax) filled by n wedge-shaped sectors, making the
   midpoint sector sum visible as it converges to the exact polar area A = ½∫₀^{θmax} r² dθ. */
(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.polar(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 PolarFig({ task, setTask, tasks, report, event, done }) {
    const [a, setA] = useState(2);
    const [thMax, setThMax] = useState(360);
    const [n, setN] = useState(6);
    const fld = useMemo(() => compute({ a, thMax, n }), [a, thMax, n]);
    useEffect(() => { report(fld); }, [a, thMax, n]); // eslint-disable-line

    // polar axes centered on the LEFT half of the 600x300 canvas.
    const CX = 180, CY = 150;
    const aa = Math.max(0.5, a);
    const thR = Math.max(0.1, thMax * Math.PI / 180);
    const ni = Math.max(1, Math.round(n));
    const rf = (t) => aa * (1 + Math.cos(t));
    // scale: max radius of the full cardioid is 2a; fit it into ~120px.
    const scale = 120 / (2 * aa);
    const px = (t) => CX + rf(t) * Math.cos(t) * scale;
    const py = (t) => CY - rf(t) * Math.sin(t) * scale;

    // the full cardioid as a polyline (sample θ 0..360).
    const SAMP = 180;
    let curvePts = [];
    for (let i = 0; i <= SAMP; i++) { const t = (i / SAMP) * 2 * Math.PI; curvePts.push(`${px(t).toFixed(1)},${py(t).toFixed(1)}`); }
    const curve = curvePts.join(" ");

    // the swept region 0→θmax filled with n wedge-shaped sectors (triangles from the origin).
    const dt = thR / ni;
    const sectors = [];
    for (let i = 0; i < ni; i++) {
      const t0 = i * dt, t1 = (i + 1) * dt, tm = (i + 0.5) * dt;
      const d = `M ${CX} ${CY} L ${px(t0).toFixed(1)} ${py(t0).toFixed(1)} L ${px(t1).toFixed(1)} ${py(t1).toFixed(1)} Z`;
      const shade = (i % 2 === 0) ? 0.32 : 0.2;
      sectors.push(<path key={i} d={d} fill={C.blue} fillOpacity={shade} stroke={C.line} strokeWidth="0.6" />);
    }

    const t = tasks.find((x) => x.id === task) || tasks[0];
    const okColor = fld.converged ? C.teal : C.amber;
    const X1 = 380;

    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 }}>
          {/* polar axes */}
          <line x1={CX - 130} y1={CY} x2={CX + 130} y2={CY} stroke={C.faint} strokeWidth="1" strokeDasharray="4 3" />
          <line x1={CX} y1={CY - 130} x2={CX} y2={CY + 130} stroke={C.faint} strokeWidth="1" strokeDasharray="4 3" />
          {/* the swept sectors */}
          {sectors}
          {/* the full cardioid */}
          <polyline points={curve} fill="none" stroke={C.gold} strokeWidth="2" />
          {/* origin */}
          <circle cx={CX} cy={CY} r="2.5" fill={C.faint} />
          {/* readout panel on the right */}
          <text x={X1 + 36} y={40} fill={C.mute} fontSize="12" fontFamily="monospace">r = a(1+cosθ), sweep 0→{fmt(thMax)}°</text>
          <text x={X1 + 36} y={66} fill={C.blue} fontSize="13" fontFamily="monospace">sector sum = {fmt(fld.riemann)}</text>
          <text x={X1 + 36} y={88} fill={C.teal} fontSize="13" fontFamily="monospace">exact A = {fmt(fld.area)}</text>
          <text x={X1 + 36} y={110} fill={okColor} fontSize="13" fontFamily="monospace">error = {fmt(fld.error)}</text>
          <text x={X1 + 36} y={132} fill={C.mute} fontSize="12" fontFamily="monospace">{fld.nSectors} sectors · rMax {fmt(fld.rMax)}</text>
        </svg>
        <div style={{ marginTop: 10, padding: "8px 12px", borderRadius: 6, background: C.panel, border: `1px solid ${fld.converged ? C.teal : C.line}`, color: fld.converged ? C.teal : C.mute, fontSize: 12.5 }}>
          Midpoint sector sum = {fmt(fld.riemann)} vs exact polar area ½∫r²dθ = {fmt(fld.area)}. {fld.converged ? <>⚑ <K.T>Converged — the sector sum has closed onto the exact area.</K.T></> : <K.T>Not converged yet — add sectors (raise n) to shrink the error.</K.T>}
        </div>
        <Slider label="cardioid size a" value={a} set={setA} min={0.5} max={3} step={0.5} unit="" color={C.teal} onUp={() => event("adjusted", `Set a = ${fmt(a)}`, { response: `area ${fmt(fld.area)}` }, C.teal)} />
        <Slider label="sweep θmax" value={thMax} set={(v) => setThMax(Math.round(v))} min={30} max={360} step={15} unit="°" color={C.gold} onUp={() => event("adjusted", `Set θmax = ${fmt(Math.round(thMax))}°`, { response: `area ${fmt(fld.area)}` }, C.gold)} />
        <Slider label="sectors n" value={n} set={(v) => setN(Math.round(v))} min={1} max={60} step={1} unit="" color={C.blue} onUp={() => event("adjusted", `Set n = ${fmt(Math.round(n))}`, { response: `error ${fmt(fld.error)}` }, C.blue)} />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 8, marginTop: 12 }}>
          <StatMeter label="exact area" v={fld.area} d={2} color={C.teal} />
          <StatMeter label="sector sum" v={fld.riemann} d={2} color={C.blue} />
          <StatMeter label="error" v={fld.error} d={3} color={okColor} />
          <StatMeter label="# sectors" v={fld.nSectors} d={0} color={C.amber} />
        </div>
      </>
    );
  }

  window.PolarTutor = K.makeTutor(PolarFig, { moduleLabel: "Polar Curves & Area bench", benchId: "polar" });
})();
