/* FORGE — ScreenHeadCurve · SVG H/Q plot at rated RPM
   Babel-standalone in-browser React. NO ES imports / exports.
   Globals: React, PumpPhysics, PUMP_TENANT, navigate, registerPumpRoute, Icons (optional).
   Aliased hooks to keep window scope clean. */

(function () {
  'use strict';

  var R    = (typeof React !== 'undefined') ? React : null;
  if (!R) return;
  var uSHC = R.useState;
  var uMHC = R.useMemo;

  // Reuse the Act 1-2 paper palette (loaded after act1-2-screens.jsx in index.html).
  var PAPER_BG     = 'oklch(0.985 0.004 85)';
  var PAPER_BG_2   = 'oklch(0.93 0.005 85)';
  var PAPER_BG_3   = 'oklch(0.965 0.005 85)';
  var PAPER_INK    = 'oklch(0.16 0.01 85)';
  var PAPER_INK_2  = 'oklch(0.30 0.01 85)';
  var PAPER_INK_3  = 'oklch(0.46 0.01 85)';
  var PAPER_INK_4  = 'oklch(0.60 0.01 85)';
  var PAPER_LINE   = 'oklch(0.84 0.006 85)';
  var PAPER_LINE_S = 'oklch(0.90 0.005 85)';
  var ACCENT       = 'oklch(0.78 0.16 75)';
  var GREEN        = 'oklch(0.66 0.13 145)';
  var RED          = 'oklch(0.58 0.18 28)';
  var AMBER        = 'oklch(0.78 0.13 70)';
  var BLUE         = 'oklch(0.62 0.10 235)';

  var FONT_UI    = 'var(--font-ui)';
  var FONT_MONO  = 'var(--font-mono)';
  var FONT_SERIF = 'var(--font-serif)';

  function root() {
    return {
      background: PAPER_BG, color: PAPER_INK,
      minHeight: '100vh', overflowY: 'auto',
      fontFamily: FONT_UI, fontSize: 14, lineHeight: 1.5,
      width: '100%', position: 'absolute', inset: 0,
      WebkitFontSmoothing: 'antialiased'
    };
  }
  function container() { return { maxWidth: 1280, margin: '0 auto', padding: '32px 40px', width: '100%' }; }
  function mono() {
    return { fontFamily: FONT_MONO, fontSize: 12, letterSpacing: '0.08em', textTransform: 'uppercase', color: PAPER_INK_3 };
  }
  function Card(props) {
    var s = Object.assign({ background: PAPER_BG_3, border: '1px solid ' + PAPER_LINE, borderRadius: 10, padding: 20 }, props.style || {});
    return R.createElement('div', { style: s }, props.children);
  }
  function Pill(props) {
    var tones = {
      default: { bg: PAPER_BG_3, fg: PAPER_INK_2, bd: PAPER_LINE },
      accent:  { bg: PAPER_BG_3, fg: ACCENT,      bd: ACCENT      },
      green:   { bg: PAPER_BG_3, fg: GREEN,       bd: GREEN       },
      red:     { bg: PAPER_BG_3, fg: RED,         bd: RED         },
      amber:   { bg: PAPER_BG_3, fg: AMBER,       bd: AMBER       },
      blue:    { bg: PAPER_BG_3, fg: BLUE,        bd: BLUE        }
    };
    var p = tones[props.tone || 'default'];
    return (
      <span style={{
        display: 'inline-flex', alignItems: 'center', gap: 6,
        height: 22, padding: '0 10px', borderRadius: 999,
        fontFamily: FONT_MONO, fontSize: 12,
        letterSpacing: '0.08em', textTransform: 'uppercase',
        border: '1px solid ' + p.bd, color: p.fg, background: p.bg
      }}>{props.children}</span>
    );
  }
  function Header(props) {
    return (
      <div style={{ marginBottom: 28 }}>
        <div style={Object.assign({}, mono(), { marginBottom: 8 })}>{props.eyebrow}</div>
        <h1 style={{ fontFamily: FONT_SERIF, fontSize: 34, fontWeight: 600, letterSpacing: '-0.015em', margin: 0, color: PAPER_INK }}>{props.title}</h1>
        {props.subtitle && <div style={{ marginTop: 8, color: PAPER_INK_3, fontSize: 14 }}>{props.subtitle}</div>}
      </div>
    );
  }
  function nav(p) { if (typeof navigate === 'function') navigate(p); }

  // ─── pull SKU presets from PUMP_TENANT.cost_cascade + design.duty_envelope ───
  // duty_envelope is a NEW shape this agent adds to fixtures-pump.jsx
  function getSkuPresets() {
    var T = (typeof window !== 'undefined') ? window.PUMP_TENANT : null;
    if (!T || !T.design || !T.design.duty_envelope) {
      // Synthesise from the matcher candidates so the screen still works.
      return [
        { sku: 'M-27418', label: '1.0HP · 4″ Helios', hp: 1.0, rated_q_lpm: 40, rated_h_m: 22, impeller_eye_d_mm: 38, suction_lift_m: -3.0, friction_m: 0.5, eff_meas_pct: 41 },
        { sku: 'M-26102', label: '0.75HP · V4 carryover', hp: 0.75, rated_q_lpm: 36, rated_h_m: 18, impeller_eye_d_mm: 34, suction_lift_m: -2.5, friction_m: 0.4, eff_meas_pct: 38 },
        { sku: 'M-31507', label: '5HP · pilot scale-up', hp: 5.0, rated_q_lpm: 95, rated_h_m: 32, impeller_eye_d_mm: 52, suction_lift_m: -4.0, friction_m: 0.8, eff_meas_pct: 49 }
      ];
    }
    return T.design.duty_envelope;
  }

  // ════════════════════════════════════════════════════════════════════
  // ScreenHeadCurve
  // ════════════════════════════════════════════════════════════════════
  function ScreenHeadCurve() {
    var PP = (typeof window !== 'undefined') ? window.PumpPhysics : null;
    var presets = getSkuPresets();
    var initial = presets[0];

    var skuState = uSHC(initial.sku);
    var sku = skuState[0]; var setSku = skuState[1];

    var preset = presets.find(function (p) { return p.sku === sku; }) || initial;

    var rpmState = uSHC(preset.rpm || 2900);
    var rpm = rpmState[0]; var setRpm = rpmState[1];

    var dutyLpmState = uSHC(preset.rated_q_lpm);
    var dutyLpm = dutyLpmState[0]; var setDutyLpm = dutyLpmState[1];

    var dutyHState = uSHC(preset.rated_h_m);
    var dutyH = dutyHState[0]; var setDutyH = dutyHState[1];

    var liftState = uSHC(preset.suction_lift_m);
    var lift = liftState[0]; var setLift = liftState[1];

    // Reset state when sku changes
    R.useEffect(function () {
      setDutyLpm(preset.rated_q_lpm);
      setDutyH(preset.rated_h_m);
      setLift(preset.suction_lift_m);
      setRpm(preset.rpm || 2900);
    }, [sku]);

    // Compute curve + duty + NPSH
    var curveData = uMHC(function () {
      if (!PP) return { pts: [], duty: null, npsh_a: 0, npsh_r: 0, guard: { margin_m: 0, flag: 'red' } };
      var pts = PP.headCurvePoints({ rated_q_lpm: dutyLpm, rated_h_m: dutyH, rpm: rpm, n_points: 36 });
      var duty = PP.dutyPoint({ hp: preset.hp, head_m: dutyH, lpm: dutyLpm });
      var npshA = PP.npshAvailable({ suction_lift_m: lift, friction_m: preset.friction_m || 0.5 }).npsh_a_m;
      var npshR = PP.npshRequired({ impeller_eye_d_mm: preset.impeller_eye_d_mm, rpm: rpm, sigma: 0.10 }).npsh_r_m;
      var guard = PP.cavitationGuard({ npsh_a: npshA, npsh_r: npshR });
      return { pts: pts, duty: duty, npsh_a: npshA, npsh_r: npshR, guard: guard };
    }, [sku, dutyLpm, dutyH, lift, rpm]);

    // SVG layout
    var W = 760, H = 380, P = 56;
    var maxQ = curveData.pts.length ? curveData.pts[curveData.pts.length - 1].Q : 1;
    var maxH = 0;
    curveData.pts.forEach(function (p) { if (p.H > maxH) maxH = p.H; });
    if (maxH < 1) maxH = 1;
    // Add headroom
    var yMax = Math.ceil((maxH * 1.1) / 5) * 5;
    var xMax = Math.ceil((maxQ * 1.05) / 5) * 5;
    function xS(q) { return P + (q / xMax) * (W - P * 2); }
    function yS(h) { return H - P - (h / yMax) * (H - P * 2); }

    var pathStr = curveData.pts.map(function (pt, i) {
      return (i === 0 ? 'M ' : 'L ') + xS(pt.Q).toFixed(1) + ' ' + yS(pt.H).toFixed(1);
    }).join(' ');

    // gridlines
    var xTicks = [];
    var step = Math.max(5, Math.ceil(xMax / 6));
    for (var qx = 0; qx <= xMax; qx += step) xTicks.push(qx);
    var yTicks = [];
    var yStep = Math.max(5, Math.ceil(yMax / 6));
    for (var hy = 0; hy <= yMax; hy += yStep) yTicks.push(hy);

    var dutyTone = curveData.guard.flag === 'ok' ? 'green' : (curveData.guard.flag === 'amber' ? 'amber' : 'red');

    function field(label, valueElt) {
      return (
        <div style={{ marginBottom: 12 }}>
          <div style={Object.assign({}, mono(), { fontSize: 11, marginBottom: 4 })}>{label}</div>
          {valueElt}
        </div>
      );
    }

    function num(id, label, value, onChange, unit, step) {
      return field(label, (
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <input
            type="number"
            id={id}
            name={id}
            aria-label={label + (unit ? ' (' + unit + ')' : '')}
            value={value}
            step={step || 1}
            onChange={function (e) { onChange(Number(e.target.value)); }}
            style={{
              flex: 1, height: 36, padding: '0 10px',
              fontFamily: FONT_UI, fontSize: 14, color: PAPER_INK,
              background: PAPER_BG, border: '1px solid ' + PAPER_LINE, borderRadius: 6, outline: 'none'
            }}
          />
          <span style={{ fontFamily: FONT_MONO, fontSize: 11, color: PAPER_INK_3 }}>{unit}</span>
        </div>
      ));
    }

    return (
      <div style={root()}>
        <div style={container()}>
          <Header
            eyebrow="Forge · HEAD CURVE"
            title="Head–flow curve at rated RPM"
            subtitle="Sweep H(Q) for a SKU, mark duty, overlay NPSH margin. Tritan design eng (Devansh / Karan)."
          />

          {/* SKU chips */}
          <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', marginBottom: 20 }}>
            {presets.map(function (p) {
              var active = p.sku === sku;
              return (
                <button
                  key={p.sku}
                  onClick={function () { setSku(p.sku); }}
                  style={{
                    padding: '8px 14px', borderRadius: 8,
                    border: '1px solid ' + (active ? ACCENT : PAPER_LINE),
                    background: active ? ACCENT : PAPER_BG_3,
                    color: active ? 'oklch(0.14 0.02 55)' : PAPER_INK_2,
                    fontFamily: FONT_MONO, fontSize: 12, letterSpacing: '0.04em',
                    cursor: 'pointer'
                  }}>
                  {p.sku} · {p.label}
                </button>
              );
            })}
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 280px', gap: 24 }}>
            {/* ───── Curve plot ───── */}
            <Card style={{ padding: 24 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
                <div style={mono()}>H (m) × Q (L/min) at {rpm} rpm</div>
                <div style={{ display: 'flex', gap: 8 }}>
                  <Pill tone="accent">curve</Pill>
                  <Pill tone="red">duty</Pill>
                  <Pill tone={dutyTone}>{curveData.guard.flag === 'ok' ? 'NPSH ok' : curveData.guard.flag.toUpperCase()}</Pill>
                </div>
              </div>

              <svg width={W} height={H} style={{ display: 'block', margin: '0 auto', maxWidth: '100%' }}>
                {/* gridlines */}
                {xTicks.map(function (q) {
                  return (
                    <g key={'gx' + q}>
                      <line x1={xS(q)} y1={P} x2={xS(q)} y2={H - P} stroke={PAPER_LINE_S} strokeDasharray="2 4" />
                      <text x={xS(q)} y={H - P + 16} textAnchor="middle" fontFamily={FONT_MONO} fontSize="10" fill={PAPER_INK_4}>{q}</text>
                    </g>
                  );
                })}
                {yTicks.map(function (h) {
                  return (
                    <g key={'gy' + h}>
                      <line x1={P} y1={yS(h)} x2={W - P} y2={yS(h)} stroke={PAPER_LINE_S} strokeDasharray="2 4" />
                      <text x={P - 8} y={yS(h) + 3} textAnchor="end" fontFamily={FONT_MONO} fontSize="10" fill={PAPER_INK_4}>{h}</text>
                    </g>
                  );
                })}
                {/* axes */}
                <line x1={P} y1={H - P} x2={W - P} y2={H - P} stroke={PAPER_LINE} />
                <line x1={P} y1={P}     x2={P}     y2={H - P} stroke={PAPER_LINE} />
                <text x={W / 2} y={H - 12} textAnchor="middle" fontFamily={FONT_MONO} fontSize="11" fill={PAPER_INK_3}>FLOW · L/min</text>
                <text x={14} y={H / 2} transform={'rotate(-90 14 ' + (H / 2) + ')'} textAnchor="middle" fontFamily={FONT_MONO} fontSize="11" fill={PAPER_INK_3}>HEAD · m</text>

                {/* NPSH margin band (NPSH_a vs NPSH_r) — drawn under the curve */}
                <line x1={P} y1={yS(curveData.npsh_a)} x2={W - P} y2={yS(curveData.npsh_a)}
                  stroke={BLUE} strokeWidth="1.5" strokeDasharray="6 3" />
                <text x={W - P + 4} y={yS(curveData.npsh_a) + 4}
                  fontFamily={FONT_MONO} fontSize="10" fill={BLUE}>NPSH_a {curveData.npsh_a.toFixed(1)}m</text>
                <line x1={P} y1={yS(curveData.npsh_r)} x2={W - P} y2={yS(curveData.npsh_r)}
                  stroke={dutyTone === 'green' ? GREEN : (dutyTone === 'amber' ? AMBER : RED)}
                  strokeWidth="1.5" strokeDasharray="3 3" />
                <text x={W - P + 4} y={yS(curveData.npsh_r) + 4}
                  fontFamily={FONT_MONO} fontSize="10"
                  fill={dutyTone === 'green' ? GREEN : (dutyTone === 'amber' ? AMBER : RED)}>NPSH_r {curveData.npsh_r.toFixed(1)}m</text>

                {/* Head curve */}
                <path d={pathStr} stroke={ACCENT} strokeWidth="2.5" fill="none" />

                {/* Duty point cross-hairs */}
                <g>
                  <line x1={xS(dutyLpm)} y1={P} x2={xS(dutyLpm)} y2={yS(dutyH)} stroke={RED} strokeDasharray="3 3" />
                  <line x1={P} y1={yS(dutyH)} x2={xS(dutyLpm)} y2={yS(dutyH)} stroke={RED} strokeDasharray="3 3" />
                  <circle cx={xS(dutyLpm)} cy={yS(dutyH)} r="6" fill={RED} stroke={PAPER_BG} strokeWidth="2" />
                  <text x={xS(dutyLpm) + 10} y={yS(dutyH) - 8}
                    fontFamily={FONT_MONO} fontSize="11" fill={RED} fontWeight="600">
                    duty {dutyLpm} L/min @ {dutyH}m
                  </text>
                </g>
              </svg>

              {/* readout strip */}
              <div style={{ marginTop: 16, display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12 }}>
                <div>
                  <div style={mono()}>RPM</div>
                  <div style={{ fontFamily: FONT_MONO, fontSize: 20, color: PAPER_INK }}>{curveData.duty ? curveData.duty.rpm : '—'}</div>
                </div>
                <div>
                  <div style={mono()}>Efficiency</div>
                  <div style={{ fontFamily: FONT_MONO, fontSize: 20, color: PAPER_INK }}>{curveData.duty ? curveData.duty.eff_pct + '%' : '—'}</div>
                </div>
                <div>
                  <div style={mono()}>Shaft kW</div>
                  <div style={{ fontFamily: FONT_MONO, fontSize: 20, color: PAPER_INK }}>{curveData.duty ? curveData.duty.power_kw : '—'}</div>
                </div>
                <div>
                  <div style={mono()}>NPSH margin</div>
                  <div style={{ fontFamily: FONT_MONO, fontSize: 20, color: dutyTone === 'green' ? GREEN : (dutyTone === 'amber' ? AMBER : RED) }}>{curveData.guard.margin_m.toFixed(2)}m</div>
                </div>
              </div>
            </Card>

            {/* ───── Inputs sidebar ───── */}
            <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
              <Card>
                <div style={Object.assign({}, mono(), { marginBottom: 14 })}>Duty inputs</div>
                {num('head-curve-flow', 'Duty flow', dutyLpm, setDutyLpm, 'L/min', 1)}
                {num('head-curve-head', 'Duty head', dutyH, setDutyH, 'm', 1)}
                {num('head-curve-rpm', 'Rated RPM', rpm, setRpm, 'rpm', 50)}
                {num('head-curve-suction-lift', 'Suction lift', lift, setLift, 'm (− submerged)', 0.1)}
              </Card>

              <Card style={{ background: PAPER_BG_2 }}>
                <div style={Object.assign({}, mono(), { marginBottom: 10 })}>Cavitation guard</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 13 }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                    <span style={{ color: PAPER_INK_3 }}>NPSH available</span>
                    <span style={{ fontFamily: FONT_MONO }}>{curveData.npsh_a.toFixed(2)} m</span>
                  </div>
                  <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                    <span style={{ color: PAPER_INK_3 }}>NPSH required</span>
                    <span style={{ fontFamily: FONT_MONO }}>{curveData.npsh_r.toFixed(2)} m</span>
                  </div>
                  <div style={{ display: 'flex', justifyContent: 'space-between', borderTop: '1px solid ' + PAPER_LINE, paddingTop: 6, marginTop: 4 }}>
                    <span style={{ color: PAPER_INK_2, fontWeight: 600 }}>Margin</span>
                    <span style={{ fontFamily: FONT_MONO, fontWeight: 600, color: dutyTone === 'green' ? GREEN : (dutyTone === 'amber' ? AMBER : RED) }}>{curveData.guard.margin_m.toFixed(2)} m</span>
                  </div>
                </div>
                <div style={{ marginTop: 14, fontSize: 12, color: PAPER_INK_3, lineHeight: 1.45 }}>
                  Thresholds: <span style={{ color: RED }}>red &lt; 0.6m</span> · <span style={{ color: AMBER }}>amber &lt; 1.2m</span> · <span style={{ color: GREEN }}>ok ≥ 1.2m</span>
                </div>
              </Card>

              <Card>
                <div style={Object.assign({}, mono(), { marginBottom: 10 })}>Cross-links</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 13 }}>
                  <a onClick={function () { nav('/forge/motor-sizing'); }} style={{ color: BLUE, cursor: 'pointer' }}>→ Motor sizing</a>
                  <a onClick={function () { nav('/forge/compliance'); }} style={{ color: BLUE, cursor: 'pointer' }}>→ Compliance verifier</a>
                  <a onClick={function () { nav('/forge/matcher'); }} style={{ color: BLUE, cursor: 'pointer' }}>→ Performance match</a>
                </div>
              </Card>
            </div>
          </div>
        </div>
      </div>
    );
  }

  if (typeof window !== 'undefined') {
    window.ScreenHeadCurve = ScreenHeadCurve;
    if (typeof window.registerPumpRoute === 'function') {
      window.registerPumpRoute({
        path: '/forge/head-curve', mode: 'forge', title: 'Head curve',
        renderer: function () { return R.createElement(ScreenHeadCurve); }
      });
    }
  }
})();
