/* visuals5.jsx — The Switch.
   A valve in a pipe + a switch in a circuit. Closed = flow, open = no flow.
   Truth-table style logic-gate previews. */

/* ─── ValveScene ────────────────────────────────────────────────────────
   Barrel → valve → pipe → outlet. Valve handle rotates open/closed.
   ───────────────────────────────────────────────────────────────────────── */
function ValveScene({ voltage = 6, R = 3, on = true, height = 380, showLabels = true }) {
  const W = 820, H = 460;
  const I = on ? voltage / R : 0;
  const period = flowPeriod(Math.max(0.05, I));
  const fill = fillRatio(voltage);

  const barrelCx = 110, barrelTop = 60, barrelBot = 360;
  const rimRx = 62, midRx = 80;
  const pipeY = 270;
  const pipeStart = barrelCx + 60;
  const pipeEnd = W - 80;
  const baseH = 32;

  // Valve geometry — sits in the middle of the pipe
  const valveCx = (pipeStart + pipeEnd) / 2;
  const valveR = 50;

  // Pipe is drawn as two segments (before valve, after valve) so we can
  // gap them out around the valve body.
  const preEnd = valveCx - valveR + 12;
  const postStart = valveCx + valveR - 12;

  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={height}
         preserveAspectRatio="xMidYMid meet" style={{ display: "block", maxHeight: height }}>
      {renderBarrel({ cx: barrelCx, top: barrelTop, bot: barrelBot, rimRx, midRx, fill, idSuffix: "vs" })}

      {/* pipe before valve */}
      {renderPipe({ pipeStart, pipeEnd: preEnd, pipeY, baseH, constrictions: [],
                    current: I, period, idSuffix: "vs-pre", showOutletCap: false })}

      {/* pipe after valve */}
      {renderPipe({ pipeStart: postStart, pipeEnd, pipeY, baseH, constrictions: [],
                    current: I, period, idSuffix: "vs-post" })}

      {/* valve body — round housing */}
      <circle cx={valveCx} cy={pipeY} r={valveR}
              fill="var(--bg-card)" stroke="var(--ink)" strokeWidth="2.5" />
      <circle cx={valveCx} cy={pipeY} r={valveR - 8}
              fill="none" stroke="var(--rule-strong)" strokeWidth="1" />

      {/* gate flap — vertical when closed, horizontal when open */}
      <g transform={`translate(${valveCx} ${pipeY}) rotate(${on ? 0 : 90})`}
         style={{ transition: "transform 240ms ease" }}>
        <rect x={-baseH + 2} y={-3} width={(baseH - 2) * 2} height={6}
              fill={on ? "var(--water)" : "var(--ink)"} rx="1" />
      </g>

      {/* handle (lever) on top */}
      <g transform={`translate(${valveCx} ${pipeY - valveR}) rotate(${on ? -90 : 0})`}
         style={{ transition: "transform 240ms ease" }}>
        <line x1="0" y1="0" x2="0" y2={-26} stroke="var(--ink)" strokeWidth="3.5" strokeLinecap="round" />
        <circle cx="0" cy={-26} r="6" fill="var(--current)" stroke="var(--ink)" strokeWidth="2" />
      </g>

      {/* outlet droplets when on */}
      {on && I > 0.1 && renderOutletDroplets({ pipeEnd, pipeY, baseH, current: I, period })}

      {showLabels && (
        <g fontFamily="IBM Plex Mono, monospace" letterSpacing="0.14em">
          <text x={barrelCx - midRx + 4} y={barrelTop - 22} fontSize="24.5" fill="var(--water)">
            PRESSURE · {voltage.toFixed(1)}V
          </text>
          <text x={valveCx} y={pipeY + valveR + 28} textAnchor="middle"
                fontSize="24.5"
                fill={on ? "var(--water)" : "var(--ink-faint)"}
                style={{ transition: "fill 240ms ease" }}>
            VALVE · {on ? "OPEN" : "SHUT"}
          </text>
          <text x={pipeEnd - 100} y={pipeY - baseH - 14} fontSize="20.5"
                fill={on ? "var(--current)" : "var(--ink-faint)"}>
            FLOW · {on ? I.toFixed(2) + "A" : "0 A"}
          </text>
        </g>
      )}
    </svg>
  );
}

/* ─── SwitchCircuitScene ────────────────────────────────────────────────
   Battery → switch → resistor → bulb. Switch open/closed.
   ───────────────────────────────────────────────────────────────────────── */
function SwitchCircuitScene({ voltage = 6, R = 3, on = true, height = 380, showLabels = true }) {
  const W = 820, H = 460;
  const I = on ? voltage / R : 0;
  const period = flowPeriod(Math.max(0.05, I));
  const flowing = on && I > 0.05;

  const L = 130, R_ = 690, T = 130, B = 360;
  const batCx = L, batCy = (T + B) / 2, batHalfH = 32;
  const swCx = 280, swCy = T;
  const resCx = 460, resCy = T;
  const bulbCx = R_, bulbCy = (T + B) / 2, bulbR = 30;

  const wirePath = `
    M ${L} ${batCy - batHalfH}
    L ${L} ${T}
    L ${swCx - 26} ${T}
    M ${swCx + 26} ${T}
    L ${resCx - 50} ${T}
    M ${resCx + 50} ${T}
    L ${R_} ${T}
    L ${R_} ${bulbCy - bulbR}
    M ${R_} ${bulbCy + bulbR}
    L ${R_} ${B}
    L ${L} ${B}
    L ${L} ${batCy + batHalfH}
  `;
  const loopPath = `
    M ${L} ${batCy - batHalfH}
    L ${L} ${T} L ${R_} ${T}
    L ${R_} ${B} L ${L} ${B}
    L ${L} ${batCy + batHalfH}
    L ${L} ${batCy - batHalfH} Z
  `;

  const power = voltage * I;
  const glowOpacity = Math.max(0, Math.min(1, power / 14));

  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={height}
         preserveAspectRatio="xMidYMid meet" style={{ display: "block", maxHeight: height }}>
      <path d={wirePath} fill="none" stroke="var(--current-faint)"
            strokeWidth="9" strokeLinecap="round"
            opacity={flowing ? 0.55 : 0} style={{ transition: "opacity 200ms ease" }} />
      <path d={wirePath} fill="none" stroke="var(--ink)" strokeWidth="2.5" strokeLinecap="round" />

      {renderElectrons({ path: loopPath, period, flowing, count: 6 })}

      {renderBatterySymbol({ cx: batCx, cy: batCy, halfH: batHalfH, voltage, showLabel: showLabels })}

      {/* Switch — animated lever */}
      <g>
        <circle cx={swCx - 26} cy={swCy} r="4" fill="var(--ink)" />
        <circle cx={swCx + 26} cy={swCy} r="4" fill="var(--ink)" />
        <g transform={`translate(${swCx - 26} ${swCy}) rotate(${on ? 0 : -38})`}
           style={{ transition: "transform 240ms ease", transformOrigin: "0 0" }}>
          <line x1="0" y1="0" x2={52} y2="0"
                stroke={on ? "var(--water)" : "var(--ink)"}
                strokeWidth="3" strokeLinecap="round"
                style={{ transition: "stroke 240ms ease" }} />
        </g>
        {showLabels && (
          <text x={swCx} y={swCy - 32} textAnchor="middle"
                fontFamily="IBM Plex Mono, monospace" fontSize="19"
                fill={on ? "var(--water)" : "var(--ink-faint)"}
                letterSpacing="0.14em" style={{ transition: "fill 240ms ease" }}>
            SWITCH · {on ? "CLOSED" : "OPEN"}
          </text>
        )}
      </g>

      {renderResistorSymbol({ cx: resCx, cy: resCy, w: 100, h: 30, r: R,
                              label: showLabels && `R · ${R.toFixed(1)}Ω` })}

      {renderBulbSymbol({ cx: bulbCx, cy: bulbCy, r: bulbR, glowOpacity, flowing,
                          label: showLabels && (flowing ? "LIT" : "DARK") })}

      {showLabels && (
        <text x={(L + R_) / 2} y={B + 30}
              fontFamily="IBM Plex Mono, monospace" fontSize="19"
              fill={flowing ? "var(--current)" : "var(--ink-faint)"}
              letterSpacing="0.14em" textAnchor="middle"
              style={{ transition: "fill 240ms ease" }}>
          I = {I.toFixed(2)}A
        </text>
      )}
    </svg>
  );
}

/* ─── LogicGateBox — tiny visual of two switches in series (AND) or parallel (OR) ─ */

function LogicGateBox({ kind, a, b }) {
  const W = 280, H = 130;
  const out = kind === "and" ? (a && b) : (a || b);
  const flowing = out;

  if (kind === "and") {
    // A → B in series, then to bulb
    const wirePath = `M 16 80 L 60 80 M 92 80 L 144 80 M 176 80 L 240 80
                      L 240 110 L 16 110 L 16 80`;
    const loop = `M 16 80 L 240 80 L 240 110 L 16 110 Z`;
    return (
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: "block", maxWidth: W }}>
        <path d={wirePath} fill="none" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" />
        {flowing && renderElectrons({ path: loop, period: "2s", flowing: true, count: 3 })}
        {/* Switch A */}
        <SwitchLittle x={60} y={80} on={a} label="A" />
        {/* Switch B */}
        <SwitchLittle x={144} y={80} on={b} label="B" />
        {/* Bulb */}
        <circle cx={232} cy={80} r={9} fill="var(--bg-card)" stroke="var(--ink)" strokeWidth="2"
                style={{ filter: flowing ? "drop-shadow(0 0 8px var(--current))" : "none" }} />
        <path d="M 226 74 L 238 86 M 238 74 L 226 86"
              stroke={flowing ? "var(--current-deep)" : "var(--ink-soft)"} strokeWidth="1.5" />
        {/* Battery */}
        <line x1={10} y1={86} x2={22} y2={86} stroke="var(--ink)" strokeWidth="2.5"/>
        <line x1={13} y1={104} x2={19} y2={104} stroke="var(--ink)" strokeWidth="2.5"/>
        {/* label */}
        <text x={W/2} y={22} textAnchor="middle"
              fontFamily="IBM Plex Mono, monospace" fontSize="17.5"
              fill="var(--ink-faint)" letterSpacing="0.14em">
          AND · series
        </text>
        <text x={W/2} y={H - 6} textAnchor="middle"
              fontFamily="IBM Plex Mono, monospace" fontSize="15"
              fill={flowing ? "var(--current)" : "var(--ink-faint)"}>
          {`A=${a?1:0}  B=${b?1:0}  →  ${out?1:0}`}
        </text>
      </svg>
    );
  }

  // OR — two branches in parallel. Each branch only carries electrons when
  // ITS OWN switch is closed, so opening one branch simply stops that branch
  // (no more "backwards through the open switch").
  const wirePath = `M 16 60 L 60 60 M 92 60 L 220 60
                    M 16 100 L 60 100 M 92 100 L 220 100
                    M 220 60 L 220 100
                    M 220 80 L 246 80
                    M 16 60 L 16 100`;
  const branchA = `M 16 60 L 220 60 L 220 80 L 246 80`;   // top branch → bulb
  const branchB = `M 16 100 L 220 100 L 220 80 L 246 80`; // bottom branch → bulb
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: "block", maxWidth: W }}>
      <path d={wirePath} fill="none" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" />
      {a && renderElectrons({ path: branchA, period: "2.4s", flowing: true, count: 3 })}
      {b && renderElectrons({ path: branchB, period: "2.4s", flowing: true, count: 3 })}
      <SwitchLittle x={60} y={60} on={a} label="A" />
      <SwitchLittle x={60} y={100} on={b} label="B" />
      <circle cx={252} cy={80} r={9} fill="var(--bg-card)" stroke="var(--ink)" strokeWidth="2"
              style={{ filter: flowing ? "drop-shadow(0 0 8px var(--current))" : "none" }} />
      <path d="M 246 74 L 258 86 M 258 74 L 246 86"
            stroke={flowing ? "var(--current-deep)" : "var(--ink-soft)"} strokeWidth="1.5" />
      <text x={W/2} y={22} textAnchor="middle"
            fontFamily="IBM Plex Mono, monospace" fontSize="17.5"
            fill="var(--ink-faint)" letterSpacing="0.14em">
        OR · parallel
      </text>
      <text x={W/2} y={H - 6} textAnchor="middle"
            fontFamily="IBM Plex Mono, monospace" fontSize="15"
            fill={flowing ? "var(--current)" : "var(--ink-faint)"}>
        {`A=${a?1:0}  B=${b?1:0}  →  ${out?1:0}`}
      </text>
    </svg>
  );
}

function SwitchLittle({ x, y, on, label }) {
  return (
    <g>
      <circle cx={x} cy={y} r="3" fill="var(--ink)" />
      <circle cx={x + 32} cy={y} r="3" fill="var(--ink)" />
      <g transform={`translate(${x} ${y}) rotate(${on ? 0 : -35})`}
         style={{ transition: "transform 240ms ease", transformOrigin: "0 0" }}>
        <line x1="0" y1="0" x2={32} y2="0"
              stroke={on ? "var(--water)" : "var(--ink)"}
              strokeWidth="2.5" strokeLinecap="round"
              style={{ transition: "stroke 240ms ease" }} />
      </g>
      <text x={x + 16} y={y - 12} textAnchor="middle"
            fontFamily="IBM Plex Mono, monospace" fontSize="15"
            fill={on ? "var(--water)" : "var(--ink-faint)"}>
        {label}={on ? 1 : 0}
      </text>
    </g>
  );
}

Object.assign(window, { ValveScene, SwitchCircuitScene, LogicGateBox });
