/* energylab.jsx — EnergyTutor: the cart-on-a-track energy bench. Built on window.BenchKit
   (harness) + window.BenchFields (shared field math), so this file is just the FIGURE.
   compute = window.BenchFields.energy — the SAME function server/benches/energy.js calls,
   so client and server fields are identical by construction. Sliders mass/height/speed →
   BenchFields.energy(state) → report + meters, showing the KE↔PE trade-off. */
(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.energy(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 EnergyFig({ task, setTask, tasks, report, event, done }) {
    const [mass, setMass] = useState(2);
    const [height, setHeight] = useState(5);
    const [speed, setSpeed] = useState(4);
    const fld = useMemo(() => compute({ mass, height, speed }), [mass, height, speed]);
    useEffect(() => { report(fld); }, [mass, height, speed]); // eslint-disable-line

    // track: hill from left (high) to ground (right); cart sits at a fraction of max height.
    const X0 = 60, X1 = 540, GY = 250, TOPY = 60;
    const hFrac = Math.min(1, height / 20);
    const cartY = GY - hFrac * (GY - TOPY);
    const cartX = X0 + 40 + (1 - hFrac) * 220; // higher cart sits further up-slope (left)
    // hill profile: a smooth curve from the cart's height down to the ground at the right.
    const hillPath = `M ${X0} ${cartY - 6} Q ${cartX + 60} ${cartY - 6} ${(cartX + X1) / 2} ${(cartY + GY) / 2} T ${X1} ${GY}`;
    // velocity arrow length ∝ speed (max 20 → 90px).
    const arrow = (speed / 20) * 90;
    // stacked energy bar: total height fixed band, KE+PE split by fraction.
    const total = fld.total || 1;
    const keFrac = total > 0 ? fld.ke / total : 0;
    const BARX = 470, BARY = TOPY, BARW = 26, BARH = 150;
    const keH = keFrac * BARH, peH = BARH - keH;

    const t = tasks.find((x) => x.id === task) || tasks[0];
    const mk = fld.mostlyKinetic;

    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 }}>
          {/* ground */}
          <line x1={X0} y1={GY} x2={X1} y2={GY} stroke={C.faint} strokeWidth="1.5" />
          {/* hill / track */}
          <path d={hillPath} fill="none" stroke={C.faint} strokeWidth="2" opacity="0.7" />
          {/* height reference */}
          <line x1={cartX} y1={cartY} x2={cartX} y2={GY} stroke={C.line} strokeWidth="1" strokeDasharray="3 4" />
          <text x={cartX + 6} y={(cartY + GY) / 2} fill={C.mute} fontSize="10" fontFamily="monospace">h = {fmt(height)} m</text>
          {/* cart */}
          <rect x={cartX - 16} y={cartY - 14} width={32} height={16} rx="3" fill={C.gold} opacity="0.9" />
          <circle cx={cartX - 9} cy={cartY + 2} r={4} fill={C.ink} opacity="0.7" />
          <circle cx={cartX + 9} cy={cartY + 2} r={4} fill={C.ink} opacity="0.7" />
          {/* velocity arrow */}
          <line x1={cartX + 16} y1={cartY - 6} x2={cartX + 16 + arrow} y2={cartY - 6} stroke={C.blue} strokeWidth="3" />
          <polygon points={`${cartX + 16 + arrow},${cartY - 11} ${cartX + 16 + arrow + 8},${cartY - 6} ${cartX + 16 + arrow},${cartY - 1}`} fill={C.blue} />
          <text x={cartX + 16} y={cartY - 14} fill={C.blue} fontSize="10" fontFamily="monospace">v = {fmt(speed)} m/s</text>
          {/* stacked energy bar (PE bottom, KE top) */}
          <rect x={BARX} y={BARY} width={BARW} height={BARH} fill="none" stroke={C.line} strokeWidth="1" rx="3" />
          <rect x={BARX} y={BARY + peH} width={BARW} height={keH} fill={C.teal} opacity="0.85" />
          <rect x={BARX} y={BARY} width={BARW} height={peH} fill={C.crimson} opacity="0.7" />
          <text x={BARX + BARW + 6} y={BARY + 12} fill={C.teal} fontSize="11" fontFamily="monospace">KE {fmt(fld.ke)} J</text>
          <text x={BARX + BARW + 6} y={BARY + BARH} fill={C.crimson} fontSize="11" fontFamily="monospace">PE {fmt(fld.pe)} J</text>
          <text x={BARX + BARW / 2} y={BARY - 6} textAnchor="middle" fill={C.ink} fontSize="11" fontFamily="monospace">E = {fmt(total)} J</text>
          <text x={X0} y={TOPY - 14} fill={C.mute} fontSize="11" fontFamily="monospace">E = KE + PE · m = {fmt(mass)} kg</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 }}>
          KE = ½mv² = {fmt(fld.ke)} J · PE = mgh = {fmt(fld.pe)} J · E = {fmt(total)} J. {mk ? "Mostly kinetic — energy is in motion." : "Mostly potential — raise speed or lower the cart to convert PE → KE."}
        </div>
        <Slider label="mass m" value={mass} set={setMass} min={0.5} max={10} step={0.5} unit="kg" color={C.gold} onUp={() => event("adjusted", `Set m = ${fmt(mass)} kg`, { response: `E ${fmt(fld.total)} J` }, C.gold)} />
        <Slider label="height h" value={height} set={setHeight} min={0} max={20} step={0.5} unit="m" color={C.crimson} onUp={() => event("adjusted", `Set h = ${fmt(height)} m`, { response: `PE ${fmt(fld.pe)} J` }, C.crimson)} />
        <Slider label="speed v" value={speed} set={setSpeed} min={0} max={20} step={0.5} unit="m/s" color={C.blue} onUp={() => event("adjusted", `Set v = ${fmt(speed)} m/s`, { response: `KE ${fmt(fld.ke)} J` }, C.blue)} />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 8, marginTop: 12 }}>
          <StatMeter label="kinetic KE" v={fld.ke} unit="J" color={C.teal} />
          <StatMeter label="potential PE" v={fld.pe} unit="J" color={C.crimson} />
          <StatMeter label="total E" v={fld.total} unit="J" color={C.amber} />
          <StatMeter label="speed v" v={fld.speed} unit="m/s" color={C.blue} />
        </div>
      </>
    );
  }

  window.EnergyTutor = K.makeTutor(EnergyFig, { moduleLabel: "Energy bench", benchId: "energy" });
})();
