/* Result panel pieces — ResultHeadline, DriverBreakdown, OperationalMetrics,
   SensitivityCallouts, BusinessCaseDialog, PDF preview. */

const { useState: useStateRP, useEffect: useEffectRP, useRef: useRefRP, useMemo: useMemoRP } = React;

// ============================================================
// ResultHeadline — the big slab. Year 1 net + payback + scenario badge.
// ============================================================
function ResultHeadline({ engineOutput, scenario, dense = false }) {
  const [flashing, setFlashing] = useStateRP(false);
  const prev = useRefRP(engineOutput.year1NetValue);
  useEffectRP(() => {
    const change = Math.abs(engineOutput.year1NetValue - prev.current) / Math.max(1, Math.abs(prev.current));
    if (change > 0.10) {
      setFlashing(true);
      const t = setTimeout(() => setFlashing(false), 380);
      prev.current = engineOutput.year1NetValue;
      return () => clearTimeout(t);
    }
    prev.current = engineOutput.year1NetValue;
  }, [engineOutput.year1NetValue]);

  const big = engineOutput.year1NetValue;
  const isNeg = big < 0;
  return (
    <div className={"roi-hero" + (flashing ? " flash" : "")}>
      <div className="top">
        <div>
          <span className="scenario-badge">
            <span className="dot" />
            {scenario} scenario
          </span>
        </div>
        <span style={{ fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase", color: "rgba(255,255,255,0.5)", fontWeight: 600 }}>
          Engine v{engineOutput.specVersion}
        </span>
      </div>
      <div className="label">Year 1 net value</div>
      <div className="big">
        <NumberWithExplainer driverKey="grossAnnualValue" label="Year 1 net value" engineOutput={engineOutput}>
          <span className="currency">£</span>{Math.abs(Math.round(big)).toLocaleString("en-GB")}{isNeg && <span style={{ color: "var(--fj-danger)", marginLeft: 6 }}>−</span>}
        </NumberWithExplainer>
      </div>

      <div className="pair">
        <div>
          <div className="label">Payback</div>
          <div className="sub">
            <NumberWithExplainer driverKey="paybackMonths" label="Payback" engineOutput={engineOutput}>
              {engineOutput.paybackMonths === Infinity ? "—" : fmtMonths(engineOutput.paybackMonths)}
            </NumberWithExplainer>
            <small>months</small>
          </div>
        </div>
        <div>
          <div className="label">3-year NPV</div>
          <div className="sub">
            <NumberWithExplainer driverKey="npv3yr" label="3-year NPV" engineOutput={engineOutput}>
              {fmtGbp(engineOutput.npv3yr, { compact: true })}
            </NumberWithExplainer>
            <small>@ 8%</small>
          </div>
        </div>
      </div>
      {engineOutput.maturityFactor != null && Math.abs(engineOutput.maturityFactor - 1) > 0.05 && (
        <div style={{ marginTop: 14, fontSize: 11, letterSpacing: "0.06em", color: "rgba(255,255,255,0.55)", textTransform: "uppercase", fontWeight: 600 }}>
          {engineOutput.maturityFactor > 1
            ? `+${Math.round((engineOutput.maturityFactor - 1) * 100)}% — low current tracking visibility`
            : `${Math.round((1 - engineOutput.maturityFactor) * 100)}% reduced — existing tracking systems in place`}
        </div>
      )}
    </div>
  );
}

// ============================================================
// DriverBreakdown — stacked horizontal bar + table
// ============================================================
function DriverBreakdown({ engineOutput }) {
  const drivers = Object.entries(engineOutput.driverBreakdown)
    .map(([k, v]) => ({ key: k, value: v.value, pct: v.pctOfGross }))
    .filter((d) => d.value > 0)
    .sort((a, b) => b.value - a.value);

  const total = engineOutput.grossAnnualValue;
  const costs = engineOutput.costs;

  return (
    <div className="card">
      <div className="card__head">
        <h3>Value drivers</h3>
        <span className="meta">{drivers.length} active · {engineOutput.scenario} scenario</span>
      </div>
      <div className="card__body">
        <div className="driver-bar" aria-label={`Stacked driver breakdown totalling ${fmtGbp(total)}`}>
          {drivers.map((d, i) => (
            <span
              key={d.key}
              style={{ width: `${d.pct}%`, background: DRIVER_COLORS[i % DRIVER_COLORS.length] }}
              title={`${DRIVER_META[d.key]?.label}: ${fmtGbp(d.value)} (${d.pct.toFixed(1)}%)`}
            />
          ))}
        </div>

        <table className="driver-table">
          <thead>
            <tr>
              <th>Lever</th>
              <th className="r">Annual value</th>
              <th className="r">% of gross</th>
            </tr>
          </thead>
          <tbody>
            {drivers.map((d, i) => (
              <tr key={d.key}>
                <td>
                  <span className="swatch" style={{ background: DRIVER_COLORS[i % DRIVER_COLORS.length] }} />
                  {DRIVER_META[d.key]?.label || d.key}
                  {d.key === "qualityReduction" && <span className="indirect-flag" title="FourJaw surfaces conditions that correlate with scrap — we don't directly prevent it. Value estimated from derived revenue if annual revenue wasn't supplied.">Indirect ⓘ</span>}
                </td>
                <td className="r">
                  <NumberWithExplainer driverKey={d.key} label={DRIVER_META[d.key]?.label} engineOutput={engineOutput}>
                    {fmtGbp(d.value)}
                  </NumberWithExplainer>
                </td>
                <td className="r">{d.pct.toFixed(1)}%</td>
              </tr>
            ))}
            <tr className="total">
              <td>Gross annual value</td>
              <td className="r">
                <NumberWithExplainer driverKey="grossAnnualValue" label="Gross annual value" engineOutput={engineOutput}>
                  {fmtGbp(total)}
                </NumberWithExplainer>
              </td>
              <td className="r">100%</td>
            </tr>
            <tr className="cost">
              <td>FourJaw cost (year 1)</td>
              <td className="r neg">({fmtGbp(costs.totalCostYear1)})</td>
              <td className="r">—</td>
            </tr>
            <tr className="net total">
              <td>Year 1 net value</td>
              <td className="r">{fmtGbp(engineOutput.year1NetValue)}</td>
              <td className="r">
                {engineOutput.roi3yrPct == null ? "—" : `${Math.round(engineOutput.roi3yrPct)}% ROI`}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ============================================================
// OperationalMetrics — 5-tile grid
// ============================================================
function OperationalMetrics({ engineOutput }) {
  const op = engineOutput.operational;
  return (
    <div className="op-tiles">
      <div className="op-tile">
        <div className="lbl">Extra hours / yr</div>
        <div className="v">{Math.round(op.extraProductiveHoursPerYear).toLocaleString("en-GB")}</div>
        <div className="u">Productive machine-hours recovered</div>
      </div>
      <div className="op-tile">
        <div className="lbl">Machines avoided</div>
        <div className="v">{op.equivalentMachinesAvoided.toFixed(2)}</div>
        <div className="u">Equivalent capacity, no new capex</div>
      </div>
      <div className="op-tile">
        <div className="lbl">FTE redeployed</div>
        <div className="v">{op.fteEquivalentRedeployed.toFixed(2)}</div>
        <div className="u">Full-Time Equivalents freed from manual data collection</div>
      </div>
      <div className="op-tile">
        <div className="lbl">CO₂ avoided</div>
        <div className="v">{op.co2TonnesAvoidedPerYear.toFixed(1)}<small>t</small></div>
        <div className="u">UK grid intensity</div>
      </div>
      <div className="op-tile">
        <div className="lbl">Util uplift</div>
        <div className="v">+{op.utilisationUpliftPp}<small>pp</small></div>
        <div className="u">Utilisation percentage-point gain vs baseline</div>
      </div>
    </div>
  );
}

// ============================================================
// SensitivityCallouts — break-even framing per driver assumption
// ============================================================
function SensitivityCallouts({ engineOutput }) {
  const s = engineOutput.sensitivity || [];
  if (s.length === 0) return null;
  return (
    <div className="sens-grid">
      {s.map((row) => {
        const hasAssumption = row.assumptionValue != null && row.breakEvenAssumption != null;
        const pctOfAssumption = hasAssumption ? Math.round(row.breakEvenFraction * 100) : null;
        return (
          <div className="sens-card" key={row.driver}>
            <div className="lbl">Key assumption · {DRIVER_META[row.driver]?.label}</div>
            {hasAssumption ? (
              <>
                <div className="driver">
                  We've assumed <strong>{row.assumptionValue}{row.assumptionUnit}</strong> {row.assumptionLabel}
                </div>
                <div className="scen">The subscription pays for itself at</div>
                <div className="scen-v">
                  {row.breakEvenAssumption.toFixed(1)}{row.assumptionUnit}
                </div>
                <div className="break-even">
                  That's <strong>{pctOfAssumption}%</strong> of our assumption — so we only need {pctOfAssumption < 50 ? "a fraction" : "most"} of the modelled improvement to break even.
                </div>
              </>
            ) : (
              <>
                <div className="driver">Strategic driver — not assumption-sensitive in the same way.</div>
                <div className="scen">Year 1 net if this driver was zero</div>
                <div className="scen-v">{fmtGbp(engineOutput.year1NetValue - row.currentValue)}</div>
                <div className="break-even">
                  This driver contributes <strong>{fmtGbp(row.currentValue)}</strong> of the gross annual value.
                </div>
              </>
            )}
          </div>
        );
      })}
    </div>
  );
}

// ============================================================
// BusinessCaseDialog — email + company + persona form → mock generation
// ============================================================
function BusinessCaseDialog({ engineOutput, onClose, onGenerated }) {
  const [step, setStep] = useStateRP("form"); // form | generating | preview
  const [email, setEmail] = useStateRP("");
  const [company, setCompany] = useStateRP("");
  const [persona, setPersona] = useStateRP("finance_director");
  const [genStep, setGenStep] = useStateRP(0);

  const submit = (e) => {
    e?.preventDefault();
    setStep("generating");
    setGenStep(0);
    const steps = [
      "Validating engine output…",
      "Drafting the opportunity section…",
      "Building the numbers table…",
      "Adding confidence & assumptions…",
      "Rendering the PDF…",
    ];
    let i = 0;
    const tick = () => {
      i++;
      setGenStep(i);
      if (i < steps.length) setTimeout(tick, 700);
      else setTimeout(() => {
        setStep("preview");
        onGenerated?.({ email, company, persona });
      }, 600);
    };
    setTimeout(tick, 500);
  };

  if (step === "preview") {
    return (
      <div className="dialog-overlay" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
        <PdfPreview engineOutput={engineOutput} company={company} persona={persona} onClose={onClose} />
      </div>
    );
  }

  return (
    <div className="dialog-overlay" onClick={(e) => { if (e.target === e.currentTarget && step === "form") onClose(); }}>
      <div className="dialog" role="dialog" aria-label="Generate business case">
        <div className="dialog__head">
          <div className="ico">
            <img src="assets/icons/page.svg" alt="" />
          </div>
          <div>
            <h3>Get the full business case</h3>
            <div className="sub">One-page PDF · tailored to the reader · {engineOutput.scenario} scenario</div>
          </div>
          <button className="close" onClick={onClose} aria-label="Close">×</button>
        </div>

        {step === "form" && (
          <>
            <form className="dialog__body" onSubmit={submit}>
              <div className="dialog__row">
                <label className="field">
                  Work email
                  <input type="email" required value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@yourcompany.co.uk" />
                </label>
                <label className="field">
                  Company name
                  <input type="text" required value={company} onChange={(e) => setCompany(e.target.value)} placeholder="Used in the document" />
                </label>
              </div>
              <div className="dialog__row full">
                <label className="field">
                  Who's reading this?
                  <span className="hint">We'll tailor the headline metric and tone — the numbers stay the same.</span>
                  <select value={persona} onChange={(e) => setPersona(e.target.value)}>
                    <option value="finance_director">Finance Director / CFO</option>
                    <option value="managing_director">Managing Director / Owner</option>
                    <option value="operations_director">Operations Director</option>
                    <option value="ci_manager">Continuous Improvement Manager</option>
                  </select>
                </label>
              </div>
            </form>
            <div className="dialog__foot">
              <div className="note">We'll email a copy and offer direct download. No tracking pixels.</div>
              <div className="row-flex">
                <button className="btn ghost" onClick={onClose}>Cancel</button>
                <button className="btn primary" onClick={submit}>Generate</button>
              </div>
            </div>
          </>
        )}

        {step === "generating" && (
          <div className="gen-progress">
            {["Validating engine output", "Drafting the opportunity section", "Building the numbers table", "Adding confidence & assumptions", "Rendering the PDF"].map((s, i) => (
              <div key={s} className={"step " + (i < genStep ? "done" : i === genStep ? "active" : "")}>
                <span className="marker" />
                <span>{s}</span>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

// ============================================================
// PdfPreview — mock of the generated one-page business case
// ============================================================
const PERSONA_HEADLINES = {
  finance_director: (eo, company) =>
    `Payback in ${fmtMonths(eo.paybackMonths)} months, with a £${Math.round(eo.npv3yr/1000)}k three-year NPV at an 8% discount rate.`,
  managing_director: (eo, company) =>
    `${Math.round(eo.operational.extraProductiveHoursPerYear).toLocaleString("en-GB")} extra productive machine-hours a year — equivalent to ${eo.operational.equivalentMachinesAvoided.toFixed(1)} machines you don't need to buy.`,
  operations_director: (eo, company) =>
    `+${eo.operational.utilisationUpliftPp} percentage points of utilisation and ${fmtGbp(eo.driverDetail.downtimeRecovery.adjusted)} of recovered unplanned downtime in the first year.`,
  ci_manager: (eo, company) =>
    `${Math.round(eo.driverDetail.labourRedeployment.manualDataHoursPerYear).toLocaleString("en-GB")} hours/yr of manual data collection eliminated, with ${(eo.operational.fteEquivalentRedeployed).toFixed(2)} FTE redeployed to improvement work.`,
};
const PERSONA_NEXT = {
  finance_director: "Book a 30-minute review of these assumptions with our team — we'll walk through every figure.",
  managing_director: "Arrange a site visit to a comparable customer running FourJaw across a similar machine fleet.",
  operations_director: "Set up a two-week trial on three representative machines to validate the utilisation baseline.",
  ci_manager: "Schedule a working session on how FourJaw's downtime taxonomy maps to your existing improvement boards.",
};
const PERSONA_LABEL = {
  finance_director:    "Finance Director / CFO",
  managing_director:   "Managing Director / Owner",
  operations_director: "Operations Director",
  ci_manager:          "Continuous Improvement Manager",
};

function PdfPreview({ engineOutput, company, persona, onClose }) {
  const eo = engineOutput;
  const drivers = Object.entries(eo.driverBreakdown)
    .filter(([k, v]) => v.value > 0)
    .sort((a, b) => b[1].value - a[1].value);

  const personaLabel = PERSONA_LABEL[persona];
  const company_ = company || "[Company name]";
  const scenarioCap = eo.scenario[0].toUpperCase() + eo.scenario.slice(1);

  return (
    <div className="dialog" style={{ width: 820, maxHeight: "92vh", overflow: "hidden", display: "flex", flexDirection: "column" }} role="dialog" aria-label="Business case preview">
      <div className="dialog__head">
        <div className="ico"><img src="assets/icons/page.svg" alt="" /></div>
        <div>
          <h3>Business case preview</h3>
          <div className="sub">{company_} · {personaLabel} · {scenarioCap}</div>
        </div>
        <button className="close" onClick={onClose} aria-label="Close">×</button>
      </div>
      <div className="pdf-frame" style={{ overflowY: "auto" }}>
        <div className="pdf-page">
          <div className="pdf-head">
            <div className="logo"><img src="assets/logo-primary.svg" alt="FourJaw" /></div>
            <div className="meta">
              {company_}<br />
              {new Date().toLocaleDateString("en-GB", { day: "numeric", month: "long", year: "numeric" })}
            </div>
          </div>

          <h2>{company_} — FourJaw business case</h2>
          <p style={{ fontSize: 14, color: "var(--fj-ink)", fontWeight: 500, letterSpacing: "-0.01em", borderLeft: "2px solid var(--fj-purple)", paddingLeft: 14, marginBottom: 22 }}>
            <strong>For {personaLabel}:</strong> {PERSONA_HEADLINES[persona](eo, company_)}
          </p>

          <h3>The opportunity</h3>
          <p>FourJaw clamps directly to your machine power cables and captures real-time utilisation, downtime cause, OEE and energy consumption — no PLC integration, no IT project. Most engaged customers see a ten-percentage-point uplift in utilisation within months; some have seen a 65% capacity boost (Armac Martin).</p>
          <p>In your specific operation, the bulk of the value comes from the top two levers: <strong>{DRIVER_META[drivers[0]?.[0]]?.label}</strong> at <strong>{fmtGbp(drivers[0]?.[1].value)}/yr</strong>{drivers[1] ? <> and <strong>{DRIVER_META[drivers[1]?.[0]]?.label}</strong> at <strong>{fmtGbp(drivers[1]?.[1].value)}/yr</strong></> : ""}. The supporting levers add the rest.</p>

          <h3>The numbers ({scenarioCap} scenario)</h3>
          <table className="pdf-table">
            <tbody>
              {drivers.map(([k, v]) => (
                <tr key={k}>
                  <td>{DRIVER_META[k]?.label}{k === "qualityReduction" && " (indirect)"}</td>
                  <td>{fmtGbp(v.value)}</td>
                </tr>
              ))}
              <tr className="total">
                <td>Gross annual value</td>
                <td>{fmtGbp(eo.grossAnnualValue)}</td>
              </tr>
              <tr>
                <td>FourJaw cost (year 1)</td>
                <td>({fmtGbp(eo.costs.totalCostYear1)})</td>
              </tr>
              <tr className="total">
                <td>Year 1 net value</td>
                <td>{fmtGbp(eo.year1NetValue)}</td>
              </tr>
            </tbody>
          </table>
          <p style={{ marginTop: 4 }}>
            Payback in <strong>{fmtMonths(eo.paybackMonths)} months</strong>. Three-year NPV: <strong>{fmtGbp(eo.npv3yr)}</strong>. ROI: <strong>{fmtPct(eo.roi3yrPct, 0)}</strong>.
          </p>

          <h3>Confidence &amp; assumptions</h3>
          <ul>
            <li>Numbers shown use the <strong>{scenarioCap}</strong> scenario; uplift factors are intentionally below what most engaged customers achieve.</li>
            <li>{eo.appliedDefaults.length} sector defaults were applied where measured data was unavailable; full list provided as an annexe.</li>
            <li>Quality reduction is an <strong>indirect lever</strong> — FourJaw does not prevent scrap; it surfaces conditions that correlate with it. We list it last for that reason.</li>
            <li>Downtime recovery includes a guardrail (overlap factor) to avoid double-counting hours already attributed to utilisation uplift.</li>
            <li>FourJaw will measure your actual utilisation and downtime patterns in the first two weeks of deployment — this number will be refined against real telemetry.</li>
          </ul>

          <h3>Next step</h3>
          <p style={{ marginBottom: 6 }}>{PERSONA_NEXT[persona]}</p>

          <div className="pdf-foot">
            Generated {new Date().toLocaleDateString("en-GB")} · Spec version {eo.specVersion} · Scenario: {scenarioCap}<br />
            FourJaw Manufacturing Analytics, Sheffield · fourjaw.com
          </div>
        </div>
      </div>
      <div className="dialog__foot">
        <div className="note">PDF will be emailed to {/* sanitise */}<strong>{ "the address you provided" }</strong>. This preview is interactive — click any number on the page to see its working.</div>
        <div className="row-flex">
          <button className="btn ghost" onClick={onClose}>Close</button>
          <button className="btn primary" onClick={onClose}>Download PDF</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  ResultHeadline, DriverBreakdown, OperationalMetrics, SensitivityCallouts, BusinessCaseDialog, PdfPreview,
});
