/* waterfall.jsx — WaterfallScene: voltage = height, made literal.
   Series: one stream over two falls in line (heights add, same stream).
   Parallel: two falls side by side off the same cliff (full height each, streams add).
   Height = V (push spent) · stream width = I (flow). Prefix: wf*. Used by chapter2.jsx. */

function wfStream(x, yTop, yBot, w, key) {
  // a substantial falling sheet: filled body + edge lines + animated fall dashes + splash
  const h = yBot - yTop;
  return (
    <g key={key}>
      <path d={`M${x - w / 2} ${yTop} q${-w * 0.12} ${h * 0.5} 0 ${h} h${w} q${w * 0.12} ${-h * 0.5} 0 ${-h} Z`}
            fill="var(--water)" opacity="0.55" />
      <path d={`M${x - w / 2} ${yTop} q${-w * 0.12} ${h * 0.5} 0 ${h}`} fill="none" stroke="var(--water-deep)" strokeWidth="2" opacity="0.6" />
      <path d={`M${x + w / 2} ${yTop} q${w * 0.12} ${h * 0.5} 0 ${h}`} fill="none" stroke="var(--water-deep)" strokeWidth="2" opacity="0.6" />
      {[-0.28, 0, 0.28].map((f, i) => (
        <line key={i} x1={x + f * w} y1={yTop + 4} x2={x + f * w} y2={yBot - 2}
              stroke="var(--water-faint)" strokeWidth={Math.max(2, w * 0.16)}
              strokeDasharray="8 12" className="wf-fall" style={{ animationDelay: `${i * -0.3}s` }} opacity="0.9" />
      ))}
      <g className="wf-splash" opacity="0.7">
        <path d={`M${x - w / 2 - 8} ${yBot - 4} q4 -8 8 0 M${x + w / 2} ${yBot - 4} q4 -8 8 0`}
              fill="none" stroke="var(--water-soft)" strokeWidth="2" />
      </g>
    </g>
  );
}

function wfBracket(x, y1, y2, side, text, strong) {
  // measuring bracket for a voltage drop: |—— with arrowheads
  const dir = side === "left" ? -1 : 1;
  const tx = x + dir * 10;
  return (
    <g>
      <line x1={x} y1={y1} x2={x} y2={y2} stroke={strong ? "var(--ink-soft)" : "var(--rule-strong)"} strokeWidth="2" />
      <path d={`M${x - 5} ${y1 + 7} L${x} ${y1 + 1} L${x + 5} ${y1 + 7} M${x - 5} ${y2 - 7} L${x} ${y2 - 1} L${x + 5} ${y2 - 7}`}
            fill="none" stroke={strong ? "var(--ink-soft)" : "var(--rule-strong)"} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
      <text x={tx} y={(y1 + y2) / 2 + 4} textAnchor={side === "left" ? "end" : "start"}
            fontFamily="IBM Plex Mono" fontSize="13" fontWeight="600" fill="var(--ink)">{text}</text>
    </g>
  );
}

function WaterfallScene({ v, r1, r2, topology, kids, height = 400 }) {
  const W = 460, H = 348;
  const yTop = 52, yBot = 300;
  const full = yBot - yTop;
  const I_s = v / (r1 + r2);
  const I1 = v / r1, I2 = v / r2;
  const wOf = I => Math.max(6, Math.min(44, I * 6));
  const deep = "var(--water-deep)";
  const lbl = { fontFamily: "IBM Plex Mono", fontSize: 11, fill: "var(--ink-soft)" };
  const cap = { fontFamily: "IBM Plex Mono", fontSize: 11.5, fontWeight: 600, fill: "var(--ink)" };
  const ground = (d) => <path d={d} fill="var(--bg-deeper)" stroke={deep} strokeWidth="3" strokeLinejoin="round" />;
  const pool = (x, y, rx) => (
    <g>
      <ellipse cx={x} cy={y} rx={rx} ry="8" fill="var(--water)" opacity="0.5" />
      <ellipse cx={x} cy={y} rx={rx} ry="8" fill="none" stroke={deep} strokeWidth="1.5" opacity="0.5" />
    </g>
  );

  let scene;
  if (topology === "series") {
    const yLedge = yTop + full * (r1 / (r1 + r2));
    const w = wOf(I_s);
    scene = (
      <g>
        {ground(`M28 ${H} V${yTop + 8} H${200 - w / 2 - 4} V${yLedge + 8} H${260 - w / 2 - 4} V${H} Z`)}
        {ground(`M${260 + w / 2 + 4} ${H} V${yBot + 8} H436 V${H} Z`)}
        <line x1="34" y1={yTop + 8} x2={200 - w / 2 - 2} y2={yTop + 8} stroke="var(--water)" strokeWidth="6" opacity="0.6" />
        <line x1={204 + w / 2} y1={yLedge + 8} x2={258 - w / 2} y2={yLedge + 8} stroke="var(--water)" strokeWidth="6" opacity="0.6" />
        {wfStream(200, yTop + 8, yLedge + 4, w, "f1")}
        {wfStream(260, yLedge + 8, yBot + 4, w, "f2")}
        {pool(330, yBot + 10, 80)}
        {wfBracket(140, yTop + 10, yLedge + 2, "left", kids ? "fall 1" : `V₁ ${fmt(I_s * r1, 1)}V`)}
        {wfBracket(322, yLedge + 10, yBot + 2, "right", kids ? "fall 2" : `V₂ ${fmt(I_s * r2, 1)}V`)}
        <text x="230" y="24" textAnchor="middle" style={cap}>{kids ? "SAME STREAM OVER BOTH FALLS" : `SAME STREAM = SAME CURRENT · I = ${fmt(I_s, 2)} A`}</text>
        <text x="230" y={H - 8} textAnchor="middle" style={lbl}>{kids ? "two falls stack up to the whole cliff" : `heights add: V₁ + V₂ = ${fmt(v, 1)}V — the full push, spent in two drops`}</text>
      </g>
    );
  } else {
    const wA = wOf(I1), wB = wOf(I2);
    scene = (
      <g>
        {ground(`M28 ${H} V${yTop + 8} H${150 - wA / 2 - 4} V${H} Z`)}
        {ground(`M${150 + wA / 2 + 4} ${H} V${yTop + 8} H${300 - wB / 2 - 4} V${H} Z`)}
        {ground(`M${300 + wB / 2 + 4} ${H} V${yTop + 8} H436 V${H} Z`)}
        <line x1="34" y1={yTop + 8} x2="430" y2={yTop + 8} stroke="var(--water)" strokeWidth="6" opacity="0.6" />
        {wfStream(150, yTop + 8, yBot + 4, wA, "fa")}
        {wfStream(300, yTop + 8, yBot + 4, wB, "fb")}
        {pool(150, yBot + 10, 52)}
        {pool(300, yBot + 10, 52)}
        {wfBracket(62, yTop + 10, yBot + 2, "left", kids ? "full height" : `full ${fmt(v, 1)}V`, true)}
        {wfBracket(225, yTop + 10, yBot + 2, "right", kids ? "full height too!" : `full ${fmt(v, 1)}V`, true)}
        <text x="150" y="24" textAnchor="middle" style={cap}>{kids ? "BRANCH 1" : `I₁ = ${fmt(I1, 2)} A`}</text>
        <text x="300" y="24" textAnchor="middle" style={cap}>{kids ? "BRANCH 2" : `I₂ = ${fmt(I2, 2)} A`}</text>
        <text x="230" y={H - 8} textAnchor="middle" style={lbl}>{kids ? "each fall drops the WHOLE cliff — the streams add" : `every branch gets the full push · streams add: I = ${fmt(I1 + I2, 2)} A`}</text>
      </g>
    );
  }

  return (
    <div className="wf-scene">
      <svg viewBox={`0 0 ${W} ${H}`} style={{ display: "block", width: "100%", height: "auto", maxHeight: height, margin: "0 auto" }}>
        {scene}
      </svg>
      <div className="wf-legend">
        {kids ? <span>how far it falls = the push · how fat the stream = the flow</span>
              : <span>height = voltage (push spent) · stream width = current (flow)</span>}
      </div>
    </div>
  );
}

Object.assign(window, { WaterfallScene });
