// The Abundance Model — Copolicy? NZ
// Order-of-magnitude model: configure a possible New Zealand, read the constraints.
// Same engine as the Cope? NZ calculator; serious register.

const { useState, useMemo } = React;

// --- Plausible custom-event telemetry (no-op if Plausible isn't loaded) ---
const track = (name, props) => { try { window.plausible && window.plausible(name, props ? { props } : undefined); } catch (e) {} };

const POPULATION_OPTIONS = [
  { v: 5, label: "5 million", note: "current-ish" },
  { v: 7.5, label: "7.5 million" },
  { v: 10, label: "10 million" },
  { v: 15, label: "15 million" },
  { v: 20, label: "20 million", note: "high scenario" },
];

const TWH_OPTIONS = [
  { v: 45, label: "45 TWh", note: "today" },
  { v: 90, label: "90 TWh" },
  { v: 150, label: "150 TWh" },
  { v: 300, label: "300 TWh" },
  { v: 500, label: "500 TWh", note: "abundance" },
];

const HOUSING_OPTIONS = [
  { v: "lol", label: "Under-supplied" },
  { v: "somehow", label: "Keeping pace" },
  { v: "built", label: "Ahead of demand" },
];

const WATER_OPTIONS = [
  { v: "ignored", label: "Unplanned" },
  { v: "modelled", label: "Modelled" },
  { v: "binding", label: "Actively managed" },
];

const GRID_OPTIONS = [
  { v: "scarcity", label: "Scarcity grid" },
  { v: "lattice", label: "Abundance lattice" },
];

const EXPORT_OPTIONS = [
  { v: "raw", label: "Raw inputs" },
  { v: "processed", label: "Processed goods" },
  { v: "advanced", label: "Advanced value chains" },
];

const SPEED_OPTIONS = [
  { v: "normal", label: "Current NZ" },
  { v: "urgent", label: "Urgent" },
  { v: "fast", label: "Fast-track" },
];

function compute(s) {
  const mwhPerCap = (s.twh * 1e6) / (s.pop * 1e6); // TWh/million people = MWh/person

  const housingScore = s.housing === "built" ? 90 : s.housing === "somehow" ? 50 : 15;
  const waterScore = s.water === "binding" ? 80 : s.water === "modelled" ? 60 : 25;
  const gridScore = s.grid === "lattice" ? 85 : 40;
  const energyScore = Math.min(100, (mwhPerCap / 30) * 100);
  const baseline = Math.round(
    0.30 * energyScore + 0.25 * housingScore + 0.15 * waterScore + 0.20 * gridScore + 0.10 * (s.speed === "fast" ? 90 : s.speed === "urgent" ? 65 : 35)
  );

  const popPressure = ((s.pop - 5) / 15) * 50;
  const housingPain = Math.max(0, Math.min(100, Math.round(
    (s.housing === "lol" ? 75 : s.housing === "somehow" ? 45 : 18) + popPressure
  )));

  const waterRisk = Math.round(
    (s.water === "ignored" ? 65 : s.water === "modelled" ? 35 : 12) + popPressure * 0.4
  );

  const baselineNeed = 8 * s.pop; // TWh
  const surplus = Math.max(0, s.twh - baselineNeed);
  const surplusPct = Math.round((surplus / Math.max(1, s.twh)) * 100);

  const exportMult = s.export === "advanced" ? 4.2 : s.export === "processed" ? 2.1 : 1.0;
  const exportValue = Math.round(surplus * exportMult * 0.9);
  const speedMult = s.speed === "fast" ? 1.3 : s.speed === "urgent" ? 1.0 : 0.55;
  const exportValueAdj = Math.round(exportValue * speedMult);

  // constraints (serious)
  const warnings = [];
  if (s.export === "raw" && s.twh >= 150) {
    warnings.push("Abundant clean power, exported as raw commodities. The value leaves with the ship.");
  }
  if (s.export === "raw") {
    warnings.push("Exports remain largely unprocessed — priced by the buyer, not the maker.");
  }
  if (s.grid === "scarcity" && s.twh >= 150) {
    warnings.push("Capacity built, then rationed by a scarcity-shaped grid.");
  }
  if (s.housing === "lol" && s.pop >= 10) {
    warnings.push("Housing supply has not kept pace with population.");
  }
  if (s.water === "ignored" && s.pop >= 10) {
    warnings.push("Water becomes a binding constraint at this population.");
  }
  if (s.speed === "normal" && s.twh >= 150) {
    warnings.push("Consenting timelines exceed the projects' useful horizon.");
  }
  if (baseline >= 75 && surplusPct >= 40 && s.export === "advanced") {
    warnings.push("A coherent configuration: baseline secured, surplus captured at the end of the chain.");
  }

  // verdict (serious)
  let verdict;
  if (baseline < 35) {
    verdict = "Below a decent baseline. This is a queue, not an economy.";
  } else if (baseline < 55) {
    verdict = "A larger population on the same base — less per person.";
  } else if (baseline < 75) {
    verdict = "Real production capacity, once coordination catches up.";
  } else {
    verdict = "An economy that contains an economy: warm, fed, and producing.";
  }

  return {
    mwhPerCap: Math.round(mwhPerCap * 10) / 10,
    baseline,
    housingPain,
    waterRisk,
    surplus: Math.round(surplus),
    surplusPct,
    exportValue: exportValueAdj,
    warnings,
    verdict,
  };
}

function Pill({ active, onClick, children, note }) {
  return (
    <button type="button" onClick={onClick} className={`gv-pill${active ? " is-active" : ""}`}>
      <span>{children}</span>
      {note ? <em>{note}</em> : null}
    </button>
  );
}

function Row({ label, hint, children }) {
  return (
    <div className="gv-row">
      <div className="gv-row-label">
        <span className="gv-row-num"></span>
        <div>
          <div className="gv-row-title">{label}</div>
          {hint ? <div className="gv-row-hint">{hint}</div> : null}
        </div>
      </div>
      <div className="gv-row-pills">{children}</div>
    </div>
  );
}

function Bar({ value, max = 100, tone = "green" }) {
  const pct = Math.max(0, Math.min(100, (value / max) * 100));
  return (
    <div className="gv-bar">
      <div className={`gv-bar-fill tone-${tone}`} style={{ width: pct + "%" }}></div>
    </div>
  );
}

function AbundanceModel() {
  const [s, setS] = useState({
    pop: 10,
    twh: 90,
    housing: "lol",
    water: "ignored",
    grid: "scarcity",
    export: "raw",
    speed: "normal",
  });
  const out = useMemo(() => compute(s), [s]);

  const engaged = React.useRef(false);
  const markEngaged = () => { if (!engaged.current) { engaged.current = true; track("Calc Engaged"); } };
  React.useEffect(() => { if (engaged.current) track("Calc Verdict", { verdict: out.verdict }); }, [out.verdict]);

  const set = (k) => (v) => { markEngaged(); setS((prev) => ({ ...prev, [k]: v })); };

  const presets = [
    { name: "Status quo", config: { pop: 5, twh: 45, housing: "lol", water: "ignored", grid: "scarcity", export: "raw", speed: "normal" } },
    { name: "Confidence agenda", config: { pop: 7.5, twh: 90, housing: "somehow", water: "modelled", grid: "scarcity", export: "processed", speed: "normal" } },
    { name: "Abundance plan", config: { pop: 10, twh: 300, housing: "built", water: "binding", grid: "lattice", export: "advanced", speed: "urgent" } },
    { name: "Norway path", config: { pop: 7.5, twh: 500, housing: "lol", water: "ignored", grid: "lattice", export: "raw", speed: "normal" } },
  ];

  return (
    <div className="gv-shell">
      <div className="gv-header">
        <div className="gv-header-left">
          <div className="gv-trademark">Interactive · Order-of-magnitude</div>
          <h3 className="gv-h">The Abundance Model</h3>
          <p className="gv-sub">Configure a possible New Zealand. The model reports the constraints.</p>
        </div>
        <div className="gv-presets">
          <div className="gv-presets-label">Presets</div>
          <div className="gv-presets-row">
            {presets.map((p) => (
              <button
                key={p.name}
                type="button"
                className="gv-preset"
                onClick={() => { markEngaged(); track("Calc Preset", { preset: p.name }); setS(p.config); }}
              >
                {p.name}
              </button>
            ))}
          </div>
        </div>
      </div>

      <div className="gv-body">
        <div className="gv-inputs">
          <Row label="Population" hint="How many people is the base serving?">
            {POPULATION_OPTIONS.map((o) => (
              <Pill key={o.v} active={s.pop === o.v} onClick={() => set("pop")(o.v)} note={o.note}>{o.label}</Pill>
            ))}
          </Row>
          <Row label="Electricity system" hint="Annual generation. Today: ~45 TWh.">
            {TWH_OPTIONS.map((o) => (
              <Pill key={o.v} active={s.twh === o.v} onClick={() => set("twh")(o.v)} note={o.note}>{o.label}</Pill>
            ))}
          </Row>
          <Row label="Housing supply" hint="Is delivery keeping up with population?">
            {HOUSING_OPTIONS.map((o) => (
              <Pill key={o.v} active={s.housing === o.v} onClick={() => set("housing")(o.v)}>{o.label}</Pill>
            ))}
          </Row>
          <Row label="Water" hint="Is water in the plan?">
            {WATER_OPTIONS.map((o) => (
              <Pill key={o.v} active={s.water === o.v} onClick={() => set("water")(o.v)}>{o.label}</Pill>
            ))}
          </Row>
          <Row label="Grid model">
            {GRID_OPTIONS.map((o) => (
              <Pill key={o.v} active={s.grid === o.v} onClick={() => set("grid")(o.v)}>{o.label}</Pill>
            ))}
          </Row>
          <Row label="Export model" hint="Where in the value chain do we capture?">
            {EXPORT_OPTIONS.map((o) => (
              <Pill key={o.v} active={s.export === o.v} onClick={() => set("export")(o.v)}>{o.label}</Pill>
            ))}
          </Row>
          <Row label="Delivery speed" hint="How fast can projects actually be built?">
            {SPEED_OPTIONS.map((o) => (
              <Pill key={o.v} active={s.speed === o.v} onClick={() => set("speed")(o.v)}>{o.label}</Pill>
            ))}
          </Row>
        </div>

        <aside className="gv-output">
          <div className="gv-out-head">
            <span className="gv-out-tag">Model output</span>
            <span className="gv-out-id">run #{(s.pop * 100 + s.twh).toString(16).toUpperCase()}</span>
          </div>

          <div className="gv-verdict">
            <div className="gv-verdict-label">Reading</div>
            <div className="gv-verdict-text">{out.verdict}</div>
          </div>

          <div className="gv-metrics">
            <div className="gv-metric">
              <div className="gv-metric-top">
                <span className="gv-metric-label">Energy per capita</span>
                <span className="gv-metric-val">{out.mwhPerCap}<em> MWh/yr</em></span>
              </div>
              <Bar value={out.mwhPerCap} max={40} tone="green" />
            </div>
            <div className="gv-metric">
              <div className="gv-metric-top">
                <span className="gv-metric-label">Baseline security</span>
                <span className="gv-metric-val">{out.baseline}<em>/100</em></span>
              </div>
              <Bar value={out.baseline} tone={out.baseline >= 65 ? "green" : out.baseline >= 40 ? "yellow" : "red"} />
            </div>
            <div className="gv-metric">
              <div className="gv-metric-top">
                <span className="gv-metric-label">Housing pressure</span>
                <span className="gv-metric-val">{out.housingPain}<em>/100</em></span>
              </div>
              <Bar value={out.housingPain} tone={out.housingPain >= 60 ? "red" : out.housingPain >= 35 ? "yellow" : "green"} />
            </div>
            <div className="gv-metric">
              <div className="gv-metric-top">
                <span className="gv-metric-label">Water risk</span>
                <span className="gv-metric-val">{out.waterRisk}<em>/100</em></span>
              </div>
              <Bar value={out.waterRisk} tone={out.waterRisk >= 55 ? "red" : out.waterRisk >= 30 ? "yellow" : "green"} />
            </div>
            <div className="gv-metric">
              <div className="gv-metric-top">
                <span className="gv-metric-label">Productive surplus</span>
                <span className="gv-metric-val">{out.surplus}<em> TWh ({out.surplusPct}%)</em></span>
              </div>
              <Bar value={out.surplusPct} tone="green" />
            </div>
            <div className="gv-metric gv-metric-wide">
              <div className="gv-metric-top">
                <span className="gv-metric-label">Export value potential</span>
                <span className="gv-metric-val">≈ NZ$ {out.exportValue}<em>B/yr</em></span>
              </div>
              <Bar value={out.exportValue} max={1500} tone="yellow" />
            </div>
          </div>

          <div className="gv-warnings">
            <div className="gv-warnings-label">Constraints</div>
            {out.warnings.length === 0 ? (
              <div className="gv-warning is-clean">No binding constraints at this configuration.</div>
            ) : (
              out.warnings.map((w, i) => (
                <div className="gv-warning" key={i}>
                  <span className="gv-warning-mark">!</span>
                  <span>{w}</span>
                </div>
              ))
            )}
          </div>
        </aside>
      </div>

      <div className="gv-footer">
        <span>An order-of-magnitude model, meant to frame the argument — not to size projects. Figures are illustrative; published work carries full sourcing.</span>
      </div>
    </div>
  );
}

const calcRoot = document.getElementById("calculator-root");
if (calcRoot) {
  ReactDOM.createRoot(calcRoot).render(<AbundanceModel />);
}
