/* global React, Icon, StatusChip, Drawer, DrawerHead, Tabs, Meta, Banner */
const { useState: useStateT, useEffect: useEffectT } = React;

/* ============================================================
   NBE CAPITAL ADEQUACY TEMPLATE — faithful, dynamic, evidence-bound
   Mirrors NBE CAR workbook (CET1 / AT1 / Tier 2) row-for-row.
   kind: green (section) · orange (regulatory total) · sub (computed subtotal) · item
   prov: core | manual | derived | null   (per-cell provenance, NBE-style)
   ============================================================ */
const CAR_ROWS = [
  { no: "1", label: "Common Equity Tier 1 (CET1) Capital: Instruments and Reserves", kind: "green" },
  { no: "1.1", label: "Common Shares / stock issued by the bank that meet the criteria for inclusion in CET1", amt: 9657, prov: "manual", rule: "NBE CAR §1.1", stress: 9657 },
  { no: "1.2", label: "Stock Surplus (Share Premiums arising from Item 1.1 above)", amt: 39, prov: "manual", rule: "NBE CAR §1.2", stress: 39 },
  { no: "1.3", label: "Legal / Statutory reserve", amt: 2424, prov: "core", rule: "NBE CAR §1.3", stress: 2424 },
  { no: "1.4", label: "Retained earnings", amt: null, prov: "core", rule: "NBE CAR §1.4", stress: null },
  { no: "1.5", label: "Common shares issued by consolidated subsidiaries of the bank (Minority Interest)", amt: null, prov: "manual", rule: "NBE CAR §1.5" },
  { no: "1.6", label: "Accumulated other comprehensive income and other disclosed and unencumbered reserve (only up to 50% of the revaluation reserve for property and equipment)", amt: null, prov: "core", rule: "NBE CAR §1.6" },
  { no: "1.7", label: "Bond issued by the Federal Government of Ethiopia to recapitalize a bank", amt: null, prov: "manual", rule: "NBE CAR §1.7" },
  { no: "1.8", label: "Donated Capital (approved by the National Bank)", amt: null, prov: "manual", rule: "NBE CAR §1.8" },
  { no: "1.9", label: "CET1 Capital Before Deduction = Sum of 1.1 to 1.8", amt: 12121, kind: "sub", prov: "derived", formula: "Σ 1.1 : 1.8", stress: 12121 },

  { no: "2", label: "Deduction from CET1 (Regulatory Adjustment)", kind: "green" },
  { no: "2.1", label: "Goodwill and other intangible assets", amt: 287, prov: "core", rule: "NBE CAR §2.1", stress: 287 },
  { no: "2.2", label: "Deferred tax assets", amt: null, prov: "core", rule: "NBE CAR §2.2" },
  { no: "2.3", label: "Cash flow hedge reserve (that relates to the hedging of financial instruments that are not fair valued on the balance sheet)", amt: null, prov: "core", rule: "NBE CAR §2.3" },
  { no: "2.4", label: "Cumulative gains and losses due to changes in own credit risk on fair valued financial liabilities", amt: null, prov: "core", rule: "NBE CAR §2.4" },
  { no: "2.5", label: "Defined benefit pension fund asset (and liabilities)", amt: -299, prov: "core", rule: "NBE CAR §2.5", stress: -299 },
  { no: "2.6", label: "Investment in own shares (Treasures stock CET1 capital instruments)", amt: null, prov: "manual", rule: "NBE CAR §2.6" },
  { no: "2.7", label: "Reciprocal cross holding in CET1 capital of Banking, Financial Institutions & Other Financial Entities", amt: null, prov: "manual", rule: "NBE CAR §2.7" },
  { no: "2.8", label: "Investment in Capital of Banking, Financial Institution & Other Financial Entities that are Outside the Scope of Regulatory Consolidation", amt: 220, prov: "core", rule: "NBE CAR §2.8", stress: 540, ev: "EVIDENCE_NEEDED", driver: "Cross-holding equity write-down (severe)" },
  { no: "2.9", label: "Regulatory adjustments applied to CET1 due to insufficient AT1 and/or Tier 2 capital to cover deductions", amt: null, prov: "derived", rule: "NBE CAR §2.9" },
  { no: "2.10", label: "Any other adjustments on CET1 required by the National Bank", amt: null, prov: "manual", rule: "NBE CAR §2.10" },
  { no: "2.11", label: "Total Deductions from CET1 = Sum of 2.1 to 2.10", amt: 208, kind: "sub", prov: "derived", formula: "Σ 2.1 : 2.10", stress: 528 },

  { no: "3", label: "CET1 Capital after Deduction = Difference of 1.9 & 2.11", amt: 11913, kind: "orange", prov: "derived", formula: "1.9 − 2.11", stress: 11593 },

  { no: "4", label: "Additional Tier 1 (AT1) Capital: Instruments", kind: "green" },
  { no: "4.1", label: "Instruments issued by the bank that meet the criteria for inclusion in AT1 capital", amt: null, prov: "manual", rule: "NBE CAR §4.1" },
  { no: "4.2", label: "Stock surplus (share premium) resulting from the issue of instruments included in AT1 capital", amt: null, prov: "manual", rule: "NBE CAR §4.2" },
  { no: "4.3", label: "AT1 instruments issued by consolidated subsidiaries of the bank and held by third parties (Minor Interest)", amt: null, prov: "manual", rule: "NBE CAR §4.3" },
  { no: "4.4", label: "Additional Tier 1 Before Deductions = Sum of 4.1 to 4.3", amt: 0, kind: "sub", prov: "derived", formula: "Σ 4.1 : 4.3", stress: 0 },

  { no: "5", label: "Deduction from Additional Tier 1 (Regulatory Adjustments)", kind: "green" },
  { no: "5.1", label: "Investment in own AT1 instruments", amt: null, prov: "manual", rule: "NBE CAR §5.1" },
  { no: "5.2", label: "Reciprocal cross holding in AT1 capital of Banking, Financial Institutions & Other Financial Entities", amt: null, prov: "manual", rule: "NBE CAR §5.2" },
  { no: "5.3", label: "Investment in AT1 Capital of Banking, Financial Institution & Other Financial Entities that are Outside the Scope of Regulatory Consolidation", amt: null, prov: "manual", rule: "NBE CAR §5.3" },
  { no: "5.4", label: "Regulatory adjustments applied to AT1 due to insufficient Tier 2 capital to cover deductions", amt: null, prov: "derived", rule: "NBE CAR §5.4" },
  { no: "5.5", label: "Any other adjustments on AT1 required by the National Bank", amt: null, prov: "manual", rule: "NBE CAR §5.5" },
  { no: "5.6", label: "Total Deductions from AT1 = Sum of 5.1 to 5.5", amt: 0, kind: "sub", prov: "derived", formula: "Σ 5.1 : 5.5", stress: 0 },

  { no: "6", label: "Additional Tier 1 After Deductions = Differences of 4.4 & 5.6", amt: 0, kind: "sub", prov: "derived", formula: "4.4 − 5.6", stress: 0 },
  { no: "7", label: "TOTAL TIER 1 CAPITAL AFTER DEDUCTIONS = Sum of 3 & 6", amt: 11913, kind: "orange", prov: "derived", formula: "3 + 6", stress: 11593 },

  { no: "8", label: "Tier 2 Capital: Instruments and Provisions", kind: "green" },
  { no: "8.1", label: "Instruments issued by the bank that meet the criteria for inclusion in Tier 2 capital", amt: null, prov: "manual", rule: "NBE CAR §8.1" },
  { no: "8.2", label: "Stock surplus (share premium) resulting from the issue of instruments included in Tier 2 capital", amt: null, prov: "manual", rule: "NBE CAR §8.2" },
  { no: "8.3", label: "Tier 2 Instruments issued by consolidated subsidiaries of the bank and held by third parties (Minority Interest)", amt: null, prov: "manual", rule: "NBE CAR §8.3" },
  { no: "8.4", label: "Certain loan loss provisions such as general provision / general loan-loss reserve (up to 1.25 percentage point of Credit Risk RWA)", amt: 526, prov: "derived", rule: "NBE CAR §8.4", formula: "min(1.25% × Credit RWA)", stress: 480, ev: "REVIEW_PENDING", driver: "Credit-RWA migration lowers 1.25% cap" },
  { no: "8.5", label: "Other reserves (as approved by the National Bank of Ethiopia) — Regulatory Risk reserve", amt: null, prov: "manual", rule: "NBE CAR §8.5" },
  { no: "8.6", label: "Tier 2 Capital Before Deductions = Sum of 8.1 to 8.5", amt: 526, kind: "sub", prov: "derived", formula: "Σ 8.1 : 8.5", stress: 480 },

  { no: "9", label: "Deductions from Tier 2 (Regulatory Adjustments)", kind: "green" },
  { no: "9.1", label: "Investments in own Tier 2 capital instruments", amt: null, prov: "manual", rule: "NBE CAR §9.1" },
  { no: "9.2", label: "Reciprocal cross holding in Tier 2 Capital of Banking, Financial Institutions & Other Financial Entities", amt: null, prov: "manual", rule: "NBE CAR §9.2" },
  { no: "9.3", label: "Investment in Tier 2 Capital of Banking, Financial Institution & Other Financial Entities that are Outside the Scope of Regulatory Consolidation", amt: null, prov: "manual", rule: "NBE CAR §9.3" },
  { no: "9.4", label: "Any other adjustments on Tier 2 required by the National Bank", amt: null, prov: "manual", rule: "NBE CAR §9.4" },
  { no: "9.5", label: "Total Deductions from Tier 2 = Sum of 9.1 to 9.4", amt: 0, kind: "sub", prov: "derived", formula: "Σ 9.1 : 9.4", stress: 0 },

  { no: "10", label: "Tier 2 Capital After Deductions = Difference of 8.6 & 9.5", amt: 526, kind: "orange", prov: "derived", formula: "8.6 − 9.5", stress: 480 },
  { no: "11", label: "TOTAL ELIGIBLE CAPITAL BASE = Sum of 7 & 10", amt: 12439, kind: "orange", prov: "derived", formula: "7 + 10", stress: 12073 },
];

const PROV = {
  core:    { label: "From core banking", c: "var(--green-ink)", bg: "var(--green-soft)", ic: "database" },
  manual:  { label: "Manually uploaded", c: "var(--amber)", bg: "var(--amber-soft)", ic: "upload" },
  derived: { label: "Derived / formula", c: "var(--indigo)", bg: "var(--indigo-soft)", ic: "zap" },
};
const fmt = (n) => n == null ? "" : n < 0 ? "(" + Math.abs(n).toLocaleString() + ")" : n.toLocaleString();

// The scenario the overlay is rendering — shared with Stress Lab, so the sheet is self-documenting.
const CAP_SCENARIO = { name: "Combined macro downturn", sev: "Severe", by: "Meron Haile", date: "Jun 30, 14:20" };

// severity ladder bands + a pure recompute used by both the live overlay and the compare view
const SEVS = [
  { name: "Mild", wd: 50, cut: 3, rwa: 2 },
  { name: "Moderate", wd: 100, cut: 6, rwa: 4 },
  { name: "Severe", wd: 145, cut: 9, rwa: 6.7 },
  { name: "Extreme", wd: 200, cut: 14, rwa: 11 },
];
function carMap(wd, cut, rwa) {
  const s28 = Math.round(220 * (1 + wd / 100));
  const s84 = Math.round(526 * (1 - cut / 100));
  const s211 = s28 - 12, s3 = 12121 - s211, s7 = s3, s86 = s84, s10 = s86, s11 = s7 + s10;
  const RWA_S = Math.round(95420 * (1 + rwa / 100));
  return { map: { "1.1": 9657, "1.2": 39, "1.3": 2424, "1.9": 12121, "2.1": 287, "2.5": -299, "2.8": s28, "2.11": s211, "3": s3, "4.4": 0, "5.6": 0, "6": 0, "7": s7, "8.4": s84, "8.6": s86, "9.5": 0, "10": s10, "11": s11 }, car: s11 / RWA_S * 100 };
}

function CapitalTemplate({ go }) {
  const [stress, setStress] = useStateT(false);
  const [cell, setCell] = useStateT(null);
  // in-sheet stress levers: write-down % on 2.8, cap-reduction % on 8.4, RWA inflation %
  const [shocks, setShocks] = useStateT({ "2.8": 145, "8.4": 9 });
  const [rwaInfl, setRwaInfl] = useStateT(6.7);
  const [mode, setMode] = useStateT("Manual");
  const [sevIdx, setSevIdx] = useStateT(2);
  const [sview, setSview] = useStateT("Compare");
  const bump = (no, d, min, max) => setShocks(s => ({ ...s, [no]: Math.max(min, Math.min(max, +(s[no] + d).toFixed(0))) }));

  // live recompute — every total flows from the levers (<400ms feedback)
  const s28 = Math.round(220 * (1 + shocks["2.8"] / 100));
  const s84 = Math.round(526 * (1 - shocks["8.4"] / 100));
  const s211 = s28 - 12, s3 = 12121 - s211, s7 = s3, s86 = s84, s10 = s86, s11 = s7 + s10;
  const ST = { "1.1": 9657, "1.2": 39, "1.3": 2424, "1.9": 12121, "2.1": 287, "2.5": -299, "2.8": s28, "2.11": s211, "3": s3, "4.4": 0, "5.6": 0, "6": 0, "7": s7, "8.4": s84, "8.6": s86, "9.5": 0, "10": s10, "11": s11 };
  const stOf = (r) => r.no in ST ? ST[r.no] : r.amt;

  const RWA = 95420, elig = 12439;
  const RWA_S = Math.round(RWA * (1 + rwaInfl / 100)), elig_s = s11;
  const car = ((elig / RWA) * 100).toFixed(1);
  const carS = ((elig_s / RWA_S) * 100).toFixed(1);
  const breach = +carS < 11;

  // severity quick-set: scales every lever to its band
  const SEV_28 = [50, 100, 145, 200], SEV_84 = [3, 6, 9, 14], SEV_RWA = [2, 4, 6.7, 11];
  const applySev = (i) => { setSevIdx(i); setShocks({ "2.8": SEV_28[i], "8.4": SEV_84[i] }); setRwaInfl(SEV_RWA[i]); };
  // reverse stress: write-down % that drives CAR to the 11% floor (holding other levers)
  const targetElig = 0.11 * RWA_S;
  const wBreach = Math.round(((12133 + s84 - targetElig) / 220 - 1) * 100);

  return (
    <div>
      {/* template chrome */}
      <div className="between" style={{ marginBottom: 14, flexWrap: "wrap", gap: 10 }}>
        <div className="center gap10 wrap">
          <span className="chip chip-neutral chip-lg"><Icon name="fileText" size={13} /> NBE/CAR · Eligible Capital Base</span>
          <span className="muted" style={{ fontSize: 12.5 }}>Renders the NBE Capital Adequacy workbook · figures bound to source, totals computed live</span>
        </div>
        <div className="center gap8">
          <button className={"btn btn-sm " + (stress ? "btn-dark" : "btn-ghost")} onClick={() => { if (stress) setStress(false); else { setStress(true); setSview("Compare"); } }}><Icon name="flask" size={15} /> {stress ? "Stress on" : "Stress test"}</button>
          <button className="btn btn-ghost btn-sm" disabled title="Export blocked"><Icon name="lock" size={14} /> Export to NBE workbook</button>
        </div>
      </div>

      {/* provenance legend (from the NBE Open Position template) */}
      <div className="center gap16 wrap" style={{ marginBottom: 12, fontSize: 12 }}>
        <span className="muted" style={{ fontWeight: 600 }}>Cell source:</span>
        {Object.values(PROV).map(p => (
          <span key={p.label} className="center gap6"><span style={{ width: 11, height: 11, borderRadius: 3, background: p.bg, border: "1px solid " + p.c }} /> <span style={{ color: "var(--ink-2)" }}>{p.label}</span></span>
        ))}
        <span className="center gap6"><span style={{ width: 11, height: 11, borderRadius: 3, background: "var(--red-soft)", border: "1px solid var(--red-line)" }} /> <span style={{ color: "var(--ink-2)" }}>Evidence needed</span></span>
        {stress && <span className="center gap6"><span style={{ width: 11, height: 11, borderRadius: 3, background: "var(--indigo-soft)", border: "1px solid var(--indigo)" }} /> <span style={{ color: "var(--ink-2)" }}>Stressed (analysis-only)</span></span>}
      </div>

      {stress && <div className="banner banner-indigo" style={{ marginBottom: 12, alignItems: "center", padding: "11px 15px" }}>
        <Icon name="flask" size={18} className="ic" />
        <div className="grow center gap10 wrap">
          <b>Stress overlay:</b> <span>{CAP_SCENARIO.name}</span>
          <span className="chip chip-red">{CAP_SCENARIO.sev}</span>
          <span className="chip chip-indigo"><span className="dot" />Analysis-only · never merged into the official column</span>
          <span className="muted" style={{ fontSize: 12 }}>Run by {CAP_SCENARIO.by} · {CAP_SCENARIO.date}</span>
        </div>
      </div>}

      <div style={{ display: "flex", gap: 16, alignItems: "flex-start" }}>
      <div className="grow" style={{ minWidth: 0 }}>
      <div className="xl-wrap">
        <table className={"xl" + (stress ? " xl-scroll" : "")}>
          <colgroup>
            <col style={{ width: 46 }} />
            <col style={{ width: stress ? 300 : undefined }} />
            <col style={{ width: 120 }} />
            {stress && SEVS.map(s => <col key={s.name} style={{ width: 92 }} />)}
            {stress && <col style={{ width: 104 }} />}
          </colgroup>
          <thead>
            <tr>
              <th className="xl-no"></th>
              <th style={{ textAlign: "left" }}>Meskel Bank S.C. — Capital Adequacy &nbsp;·&nbsp; ETB millions</th>
              <th className="xl-amt">Amount</th>
              {stress && SEVS.map((s, i) => <th key={s.name} className={"xl-amt xl-stress" + (sevIdx === i ? " on" : "")} style={{ cursor: "pointer" }} onClick={() => applySev(i)}>{s.name}</th>)}
              {stress && <th className="xl-amt" style={{ background: "var(--indigo)", color: "#fff", borderLeft: "2px solid var(--indigo)" }}>Custom</th>}
            </tr>
          </thead>
          <tbody>
            {CAR_ROWS.map((r, i) => {
              const cls = "xl-" + (r.kind || "item");
              const clickable = r.amt != null || r.kind === "sub" || r.kind === "orange";
              const evBad = r.ev === "EVIDENCE_NEEDED";
              return (
                <tr key={i} className={cls}>
                  <td className="xl-no">{r.no}</td>
                  <td className="xl-label">{r.label}</td>
                  <td className={"xl-amt xl-cell" + (clickable ? " hit" : "") + (evBad ? " bad" : "")}
                    onClick={clickable ? () => setCell(r) : null}>
                    {r.amt != null
                      ? <span className="center" style={{ justifyContent: "flex-end", gap: 6 }}>
                          {r.prov && <span className="prov-dot" style={{ background: evBad ? "var(--red)" : PROV[r.prov].c }} />}
                          <span className="tnum">{fmt(r.amt)}</span>
                        </span>
                      : (r.kind === "item" ? <span className="muted" style={{ opacity: .5 }}>–</span> : "")}
                  </td>
                  {stress && (() => {
                    const has = r.amt != null || r.kind === "sub" || r.kind === "orange";
                    if (!has) return <React.Fragment>{SEVS.map((s, j) => <td key={j} className="xl-amt xl-stress" />)}<td className="xl-amt" style={{ borderLeft: "2px solid var(--indigo)" }} /></React.Fragment>;
                    const shockable = r.no === "2.8" || r.no === "8.4";
                    const cv = stOf(r); const cch = cv !== r.amt; const dlt = (cv || 0) - (r.amt || 0);
                    return <React.Fragment>
                      {SEVS.map((s, j) => { const m = carMap(s.wd, s.cut, s.rwa).map; const v = r.no in m ? m[r.no] : r.amt; return <td key={j} className={"xl-amt xl-stress tnum" + (sevIdx === j ? " on" : "")} style={{ cursor: "pointer", color: v !== r.amt ? "var(--indigo)" : undefined }} onClick={() => applySev(j)}>{fmt(v)}</td>; })}
                      <td className="xl-amt xl-cell tnum" onClick={shockable ? (e) => e.stopPropagation() : null} style={{ borderLeft: "2px solid var(--indigo)", background: "rgba(79,77,208,.05)" }}>
                        <span className="col" style={{ alignItems: "flex-end", gap: 2 }}>
                          <span style={{ color: cch ? "var(--indigo)" : "var(--ink-3)", fontWeight: cch ? 700 : 400 }}>{fmt(cv)}</span>
                          {shockable && <LeverStepper value={shocks[r.no]} unit="%" label={r.no === "2.8" ? "write-down" : "cap cut"} onDec={() => bump(r.no, -5, 0, 300)} onInc={() => bump(r.no, 5, 0, 300)} />}
                        </span>
                      </td>
                    </React.Fragment>;
                  })()}
                </tr>
              );
            })}
            <tr className="xl-sub"><td className="xl-no"></td><td className="xl-label">Total risk-weighted assets</td><td className="xl-amt tnum">{RWA.toLocaleString()}</td>{stress && <React.Fragment>{SEVS.map((s, j) => <td key={j} className={"xl-amt xl-stress tnum" + (sevIdx === j ? " on" : "")} style={{ color: "var(--indigo)" }}>{Math.round(RWA * (1 + s.rwa / 100)).toLocaleString()}</td>)}<td className="xl-amt tnum" style={{ borderLeft: "2px solid var(--indigo)", background: "rgba(79,77,208,.05)", color: "var(--indigo)" }}>{RWA_S.toLocaleString()}</td></React.Fragment>}</tr>
            <tr className="xl-sub"><td className="xl-no"></td><td className="xl-label">CET1 ratio · NBE floor 7%</td><td className="xl-amt tnum" style={{ color: "var(--green-ink)" }}>{(s3 / RWA * 100).toFixed(1)}%</td>{stress && <React.Fragment>{SEVS.map((s, j) => { const m = carMap(s.wd, s.cut, s.rwa); const cv = m.map["3"] / Math.round(RWA * (1 + s.rwa / 100)) * 100; const br = cv < 7; return <td key={j} className={"xl-amt xl-stress tnum" + (sevIdx === j ? " on" : "")} style={{ color: br ? "var(--red)" : "var(--indigo)" }}>{cv.toFixed(1)}%</td>; })}<td className="xl-amt tnum" style={{ borderLeft: "2px solid var(--indigo)", background: "rgba(79,77,208,.05)", color: (s3 / RWA_S * 100) < 7 ? "var(--red)" : "var(--indigo)" }}>{(s3 / RWA_S * 100).toFixed(1)}%</td></React.Fragment>}</tr>
            <tr className="xl-sub"><td className="xl-no"></td><td className="xl-label">Tier 1 capital ratio · NBE floor 9%</td><td className="xl-amt tnum" style={{ color: "var(--green-ink)" }}>{(s7 / RWA * 100).toFixed(1)}%</td>{stress && <React.Fragment>{SEVS.map((s, j) => { const m = carMap(s.wd, s.cut, s.rwa); const cv = m.map["7"] / Math.round(RWA * (1 + s.rwa / 100)) * 100; const br = cv < 9; return <td key={j} className={"xl-amt xl-stress tnum" + (sevIdx === j ? " on" : "")} style={{ color: br ? "var(--red)" : "var(--indigo)" }}>{cv.toFixed(1)}%</td>; })}<td className="xl-amt tnum" style={{ borderLeft: "2px solid var(--indigo)", background: "rgba(79,77,208,.05)", color: (s7 / RWA_S * 100) < 9 ? "var(--red)" : "var(--indigo)" }}>{(s7 / RWA_S * 100).toFixed(1)}%</td></React.Fragment>}</tr>
            <tr className="xl-orange"><td className="xl-no"></td><td className="xl-label">Total Capital Adequacy Ratio · NBE floor 11%</td><td className="xl-amt tnum" style={{ color: "var(--green-ink)" }}>{car}%</td>{stress && <React.Fragment>{SEVS.map((s, j) => { const m = carMap(s.wd, s.cut, s.rwa); const cv = (m.map["11"] / Math.round(RWA * (1 + s.rwa / 100)) * 100); const br = cv < 11; return <td key={j} className={"xl-amt xl-stress tnum xl-cell hit" + (sevIdx === j ? " on" : "")} onClick={() => applySev(j)} style={{ background: br ? "var(--red-soft)" : undefined, color: br ? "var(--red)" : "var(--indigo)", fontWeight: 800 }}>{cv.toFixed(1)}%</td>; })}<td className="xl-amt tnum" style={{ borderLeft: "2px solid var(--indigo)", background: breach ? "var(--red-soft)" : "rgba(79,77,208,.05)", color: breach ? "var(--red)" : "var(--indigo)", fontWeight: 800 }}>{carS}%</td></React.Fragment>}</tr>
          </tbody>
        </table>
      </div>
      </div>
      {stress && <StressDock mode={mode} setMode={setMode} sevIdx={sevIdx} applySev={applySev}
        shocks={shocks} setShocks={setShocks} rwaInfl={rwaInfl} setRwaInfl={setRwaInfl}
        carS={carS} breach={breach} wBreach={wBreach} go={go}
        onReset={() => { setShocks({ "2.8": 0, "8.4": 0 }); setRwaInfl(0); }} />}
      </div>

      <div className="mt16"><Banner kind="indigo" icon="info">
        This is a <b>live render</b> of the NBE workbook. Adjust a <b>lever in the stressed column</b> (or the RWA inflation lever) and every subtotal, total, and the CAR recompute instantly — the official Amount column never changes. Push hard enough and the limit check flips to breach and offers a Recovery handoff.
      </Banner></div>

      <CellDrawer cell={cell} onClose={() => setCell(null)} stress={stress} go={go} />
    </div>
  );
}

function CarStat({ label, v, sv, foot, big, tone }) {
  const c = tone === "green" ? "var(--green-ink)" : "var(--ink)";
  return (
    <div className="card card-pad" style={{ padding: "15px 18px" }}>
      <div className="section-label">{label}</div>
      <div className="big-num tnum" style={{ marginTop: 6, color: c, fontSize: big ? 32 : 26 }}>{v}</div>
      {sv && <div className="center gap6" style={{ marginTop: 3, fontSize: 13, color: "var(--indigo)", fontWeight: 700 }}><Icon name="flask" size={12} /> <span className="tnum">{sv} stressed</span></div>}
      <div className="muted" style={{ fontSize: 11.5, marginTop: 4 }}>{foot}</div>
    </div>
  );
}

/* ---------- per-cell evidence drawer ---------- */
function CellDrawer({ cell, onClose, stress, go }) {
  const [tab, setTab] = useStateT("Cell");
  useEffectT(() => { if (cell) setTab("Cell"); }, [cell]);
  if (!cell) return null;
  const p = cell.prov ? PROV[cell.prov] : null;
  const evBad = cell.ev === "EVIDENCE_NEEDED";
  return (
    <Drawer open={!!cell} onClose={onClose}>
      <DrawerHead title={"Cell " + cell.no} sub={cell.label.length > 70 ? cell.label.slice(0, 70) + "…" : cell.label}
        chip={evBad ? <StatusChip s="EVIDENCE_NEEDED" /> : cell.kind === "orange" || cell.kind === "sub" ? <StatusChip s="REVIEW_PENDING" /> : <StatusChip s="RECONCILED" />} onClose={onClose} />
      <Tabs tabs={stress ? ["Cell", "Source", "Rule", "Stress", "Lineage"] : ["Cell", "Source", "Rule", "Lineage"]} active={tab} onChange={setTab} />
      <div className="drawer-body">
        {tab === "Cell" && <React.Fragment>
          {p && <div style={{ marginBottom: 14 }}>
            <span className="chip" style={{ background: p.bg, color: p.c, borderColor: p.c }}><Icon name={p.ic} size={13} /> {p.label}</span>
          </div>}
          <Meta rows={[
            ["Cell reference", "Capital / row " + cell.no],
            ["Official amount", <span className="tnum">Br {fmt(cell.amt)} M</span>],
            cell.formula ? ["Formula", <span className="mono">{cell.formula}</span>] : ["Entry", "Bound value"],
            stress && cell.stress != null ? ["Stressed", <span className="tnum" style={{ color: "var(--indigo)" }}>Br {fmt(cell.stress)} M</span>] : ["Stressed", "overlay off"],
          ]} />
          {evBad && <div className="mt16"><Banner kind="red" icon="alert"><b>Evidence needed.</b> This deduction lacks a verified NBE reference and a reconciled source. It blocks the CAR from advancing.</Banner></div>}
        </React.Fragment>}
        {tab === "Source" && (cell.prov === "derived"
          ? <Banner kind="indigo" icon="zap"><b>Computed cell.</b> {cell.formula ? <span>Calculated as <span className="mono">{cell.formula}</span> from the rows above — no direct source.</span> : "Derived from upstream rows."}</Banner>
          : <div>
              <div className="evi-row"><span className="ic-wrap"><Icon name={p ? p.ic : "database"} size={15} /></span><div className="grow"><div className="t">{cell.prov === "core" ? "Core Banking — capital register" : "Capital instruments register (upload)"}</div><div className="d">{cell.prov === "core" ? "T24 · reconciled to GL" : "Manual extract · checker-verified"}</div></div>{cell.prov === "core" ? <StatusChip s="RECONCILED" /> : <StatusChip s="REVIEW_PENDING" />}</div>
              <button className="btn btn-ghost btn-sm mt16" onClick={() => go("harmonizer")}><Icon name="arrowR" size={14} /> Open in Data Harmonizer</button>
            </div>)}
        {tab === "Rule" && (cell.rule
          ? <div className="evi-row"><span className="ic-wrap" style={{ color: evBad ? "var(--red)" : "var(--green-ink)" }}><Icon name="clipboard" size={15} /></span><div className="grow"><div className="t">{cell.rule}</div><div className="d">{evBad ? "Reference not yet attached" : "NBE Capital Adequacy directive"}</div></div>{evBad ? <button className="btn btn-ghost btn-sm" onClick={() => go("evidence")}>Attach</button> : <Icon name="checkCirc" size={18} style={{ color: "var(--green)" }} />}</div>
          : <div className="muted">No rule reference applies to this cell.</div>)}
        {tab === "Stress" && <React.Fragment>
          <Banner kind="indigo" icon="flask"><b>{CAP_SCENARIO.name} · {CAP_SCENARIO.sev}.</b> Analysis-only — this never overwrites the official Amount.</Banner>
          <table className="tbl mt12"><tbody>
            <tr><td className="muted">Baseline (official)</td><td className="num tnum" style={{ fontWeight: 600 }}>Br {fmt(cell.amt)} M</td></tr>
            <tr><td className="muted">Stressed</td><td className="num tnum" style={{ color: "var(--indigo)", fontWeight: 700 }}>Br {fmt(cell.stress)} M</td></tr>
            <tr><td className="muted">Movement</td><td className="num tnum" style={{ color: "var(--indigo)" }}>{(cell.stress - cell.amt) > 0 ? "▲ +" : "▼ "}{fmt(Math.abs(cell.stress - cell.amt))} M</td></tr>
          </tbody></table>

          <div className="section-label mt20 mb6">Preview logic <span style={{ textTransform: "none", fontWeight: 500, color: "var(--ink-3)" }}>· not the official NBE formula</span></div>
          <div className="mono" style={{ fontSize: 12, background: "var(--surface-2)", border: "1px solid var(--border)", borderRadius: 8, padding: "8px 10px" }}>{cell.formula || (cell.no === "2.8" ? "investment × (1 + write-down %)" : "amount × shock")}</div>

          <div className="mt16"><Meta rows={[
            ["Affected cells", <span className="mono">3 · 7 · 11</span>],
            ["Expected impact", <span style={{ color: "var(--indigo)", fontWeight: 600 }}>Eligible capital {(cell.stress - cell.amt) >= 0 ? "−" : "+"}Br {fmt(Math.abs(cell.stress - cell.amt))} M</span>],
            ["Assumption status", <span className="chip chip-amber">Approval required</span>],
            ["Computation status", <span className="chip chip-indigo">Analysis only</span>],
          ]} /></div>

          <div className="section-label mt20 mb8">Driving lever</div>
          {cell.driver
            ? <div className="evi-row"><span className="ic-wrap" style={{ color: "var(--indigo)" }}><Icon name="sliders" size={15} /></span><div className="grow"><div className="t">{cell.driver}</div><div className="d">Lever from “{CAP_SCENARIO.name}”</div></div><button className="btn btn-quiet btn-sm" onClick={() => go("stress")}><Icon name="arrowR" size={13} /></button></div>
            : <div className="muted" style={{ fontSize: 13 }}>This cell moves only as a downstream effect of the levers above — it has no direct shock applied.</div>}
          <div className="mt16"><Banner kind="green" icon="info">The official Amount stays <b>Br {fmt(cell.amt)} M</b>. Stress lives only in this overlay and the Stress Lab record.</Banner></div>
        </React.Fragment>}
        {tab === "Lineage" && <div>
          {["Source captured & hashed", "Mapped to template cell " + cell.no, "Reconciled to GL", "Rule referenced", "Approved (internal)"].map((s, i) => {
            const done = i < (evBad ? 2 : cell.prov === "core" ? 4 : 3);
            return <div key={i} className="center gap12" style={{ padding: "8px 0" }}>
              <span style={{ width: 22, height: 22, borderRadius: 50, background: done ? "var(--green)" : "var(--surface-2)", color: done ? "#fff" : "var(--ink-4)", display: "grid", placeItems: "center", border: done ? "none" : "1.5px solid var(--border-dark)" }}>{done ? <Icon name="check" size={12} /> : <span style={{ width: 5, height: 5, borderRadius: 50, background: "var(--ink-4)" }} />}</span>
              <span style={{ fontSize: 13, color: done ? "var(--ink)" : "var(--ink-3)", fontWeight: done ? 600 : 500 }}>{s}</span>
            </div>;
          })}
        </div>}
      </div>
      <div className="drawer-foot">
        <span className="muted center gap6" style={{ fontSize: 12 }}><Icon name="hash" size={14} /> NBE cell · bound to source</span>
        <button className="btn btn-dark" style={{ marginLeft: "auto" }} onClick={() => go(evBad ? "evidence" : "harmonizer")}>{evBad ? "Resolve evidence" : "Trace source"} <Icon name="arrowR" size={14} /></button>
      </div>
    </Drawer>
  );
}

function LeverStepper({ value, unit, label, onDec, onInc }) {
  return (
    <span className="lev-step" onClick={e => e.stopPropagation()} title={label ? ("Lever: " + label) : "Adjust shock"}>
      <button onClick={onDec} aria-label="decrease">−</button>
      <span className="lev-val tnum">{value}{unit}</span>
      <button onClick={onInc} aria-label="increase">+</button>
    </span>
  );
}

function CompareTable({ onOpen, live, onOpenCustom }) {
  const base = carMap(0, 0, 0);
  const cols = SEVS.map(s => ({ name: s.name, ...carMap(s.wd, s.cut, s.rwa) }));
  const val = (m, no) => no in m ? fmt(m[no]) : "";
  return (
    <React.Fragment>
      <div className="xl-wrap">
        <table className="xl xl-scroll">
          <colgroup>
            <col style={{ width: 42 }} /><col style={{ width: 300 }} /><col style={{ width: 104 }} />
            {SEVS.map(s => <col key={s.name} style={{ width: 92 }} />)}
            <col style={{ width: 104 }} />
          </colgroup>
          <thead>
            <tr>
              <th className="xl-no"></th>
              <th style={{ textAlign: "left" }}>Severity ladder · analysis-only · read-only</th>
              <th className="xl-amt">Base</th>
              {SEVS.map((s, i) => <th key={s.name} className="xl-amt xl-stress" style={{ cursor: "pointer" }} title={"Open " + s.name + " live"} onClick={() => onOpen && onOpen(i)}>{s.name} <Icon name="sliders" size={11} style={{ verticalAlign: "-1px", opacity: .6 }} /></th>)}
              <th className="xl-amt" style={{ cursor: "pointer", background: "var(--indigo)", color: "#fff", borderLeft: "2px solid var(--indigo)" }} title="Edit your own shock live" onClick={() => onOpenCustom && onOpenCustom()}>Custom <Icon name="sliders" size={11} style={{ verticalAlign: "-1px" }} /></th>
            </tr>
          </thead>
          <tbody>
            {CAR_ROWS.map((r, i) => {
              const cls = "xl-" + (r.kind || "item");
              const has = r.amt != null || r.kind === "sub" || r.kind === "orange";
              return (
                <tr key={i} className={cls}>
                  <td className="xl-no">{r.no}</td>
                  <td className="xl-label">{r.label}</td>
                  <td className="xl-amt tnum">{has ? val(base.map, r.no) : ""}</td>
                  {cols.map((c, j) => {
                    const ch = has && r.no in c.map && c.map[r.no] !== base.map[r.no];
                    return <td key={j} className="xl-amt xl-stress tnum" style={{ color: ch ? "var(--indigo)" : undefined, fontWeight: ch ? 700 : undefined }}>{has ? val(c.map, r.no) : ""}</td>;
                  })}
                  {(() => { const ch = has && live && r.no in live.map && live.map[r.no] !== base.map[r.no]; return <td className="xl-amt tnum xl-cell hit" onClick={() => onOpenCustom && onOpenCustom()} style={{ borderLeft: "2px solid var(--indigo)", color: ch ? "var(--indigo)" : undefined, fontWeight: ch ? 700 : undefined, background: "rgba(79,77,208,.05)" }}>{has && live ? val(live.map, r.no) : ""}</td>; })()}
                </tr>
              );
            })}
            <tr className="xl-orange">
              <td className="xl-no"></td>
              <td className="xl-label">Capital Adequacy Ratio (CAR) · NBE floor 11%</td>
              <td className="xl-amt tnum">{base.car.toFixed(1)}%</td>
              {cols.map((c, j) => {
                const br = c.car < 11;
                return <td key={j} className="xl-amt tnum xl-cell hit" title={"Open " + c.name + " live"} onClick={() => onOpen && onOpen(j)} style={{ background: br ? "var(--red-soft)" : undefined, color: br ? "var(--red)" : "var(--indigo)", fontWeight: 800 }}>{c.car.toFixed(1)}%</td>;
              })}
              {(() => { const br = live && live.car < 11; return <td className="xl-amt tnum xl-cell hit" onClick={() => onOpenCustom && onOpenCustom()} style={{ borderLeft: "2px solid var(--indigo)", background: br ? "var(--red-soft)" : "rgba(79,77,208,.05)", color: br ? "var(--red)" : "var(--indigo)", fontWeight: 800 }}>{live ? live.car.toFixed(1) + "%" : ""}</td>; })()}
            </tr>
          </tbody>
        </table>
      </div>
      <div className="mt16"><Banner kind="indigo" icon="flask">
        Columns show NBE's named severity bands side by side — read-only. The <b style={{ color: "var(--indigo)" }}>Custom</b> column is your own live shock; click it (or any band) to open the manipulator and fine-tune the levers. The CAR row shades red wherever a column breaches the 11% floor.
      </Banner></div>
    </React.Fragment>
  );
}

function StressDock({ mode, setMode, sevIdx, applySev, shocks, setShocks, rwaInfl, setRwaInfl, carS, breach, wBreach, go, onReset }) {
  const set28 = v => setShocks(s => ({ ...s, "2.8": +v }));
  const set84 = v => setShocks(s => ({ ...s, "8.4": +v }));
  const pos = Math.max(2, Math.min(98, ((carS - 8) / 12) * 100));
  const floorPos = ((11 - 8) / 12) * 100;
  const [submitted, setSubmitted] = useStateT(null);
  const submit = () => {
    const sc = { id: "ST-" + String(Date.now()).slice(-5), name: `Capital · WD ${shocks["2.8"]}% · RWA +${rwaInfl}%`, checker: "Meron Haile", module: "Capital Adequacy", carS };
    let arr = []; try { arr = JSON.parse(localStorage.getItem("tos_stress_approvals") || "[]"); } catch (e) {}
    arr.unshift(sc); localStorage.setItem("tos_stress_approvals", JSON.stringify(arr));
    setSubmitted(sc); window.dispatchEvent(new Event("tos-approvals"));
  };
  return (
    <aside className="stress-dock">
      <div className="between mb12"><span className="center gap8"><Icon name="sliders" size={15} style={{ color: "var(--indigo)" }} /><b style={{ fontSize: 14, whiteSpace: "nowrap" }}>Stress controls</b></span><span className="chip chip-indigo">Analysis-only</span></div>
      <div className="seg-ctl" style={{ width: "100%", marginBottom: 14 }}>{[["Presets", "Severity"], ["Custom", "Manual"], ["Reverse", "Reverse"]].map(([lbl, key]) => <button key={key} className={mode === key ? "on" : ""} style={{ flex: 1 }} onClick={() => setMode(key)}>{lbl}</button>)}</div>

      {mode === "Severity" && <div>
        <div className="dock-label">Scenario severity</div>
        <div className="seg-ctl" style={{ width: "100%" }}>{["Mild", "Mod", "Severe", "Extreme"].map((s, i) => <button key={s} className={sevIdx === i ? "on" : ""} style={{ flex: 1, padding: "6px 2px" }} onClick={() => applySev(i)}>{s}</button>)}</div>
        <div className="muted" style={{ fontSize: 11.5, marginTop: 8 }}>Scales every lever at once to NBE's named severity bands.</div>
      </div>}

      {mode === "Manual" && <div className="col" style={{ gap: 15 }}>
        <DockSlider label="Cross-holding write-down" cell="2.8" v={shocks["2.8"]} unit="%" min={0} max={250} step={5} onChange={set28} />
        <DockSlider label="Provision cap cut" cell="8.4" v={shocks["8.4"]} unit="%" min={0} max={50} step={1} onChange={set84} />
        <DockSlider label="RWA inflation" cell="RWA" v={rwaInfl} unit="%" min={0} max={40} step={0.5} onChange={v => setRwaInfl(+v)} />
      </div>}

      {mode === "Reverse" && <div>
        <div className="dock-label">Find the breaking point</div>
        <div className="muted" style={{ fontSize: 11.5, marginBottom: 10 }}>Reverse stress — solves the write-down that hits the 11% floor, holding the other levers fixed.</div>
        <div className="banner banner-indigo" style={{ padding: "11px 13px" }}><Icon name="flask" size={16} className="ic" /><div>A cross-holding write-down of <b>≈{wBreach}%</b> drives CAR to the 11% floor (other levers held).</div></div>
        <button className="btn btn-dark btn-sm" style={{ width: "100%", marginTop: 12 }} onClick={() => setShocks(s => ({ ...s, "2.8": Math.max(0, wBreach) }))}>Set to breaking point</button>
        <div className="muted" style={{ fontSize: 11.5, marginTop: 8 }}>Solves for the shock that just breaches the limit — useful for early-warning triggers.</div>
      </div>}

      <hr className="hr" style={{ margin: "16px 0" }} />
      <div className="dock-label">Live CAR (stressed)</div>
      <div className="big-num tnum" style={{ fontSize: 30, color: breach ? "var(--red)" : "var(--green-ink)", marginTop: 2 }}>{carS}%</div>
      <div className="gauge"><span className="gauge-fill" style={{ width: pos + "%", background: breach ? "var(--red)" : "var(--green)" }} /><span className="gauge-floor" style={{ left: floorPos + "%" }} /></div>
      <div className="between" style={{ fontSize: 10.5, color: "var(--ink-3)", marginTop: 3 }}><span>8%</span><span>11% floor</span><span>20%</span></div>
      {breach
        ? <button className="btn btn-dark btn-sm" style={{ width: "100%", marginTop: 12 }} onClick={() => go("recovery")}>Breach — Send to Recovery <Icon name="arrowR" size={13} /></button>
        : <div className="chip chip-green chip-lg" style={{ marginTop: 12 }}><span className="dot" />Within NBE limit</div>}
      <hr className="hr" style={{ margin: "14px 0 12px" }} />
      {submitted
        ? <div className="banner banner-green" style={{ padding: "10px 12px" }}><Icon name="checkCirc" size={16} className="ic" /><div><b>Review intent recorded for {submitted.checker}.</b> Now a pending internal task in the Control Room queue.</div></div>
        : <button className="btn btn-dark btn-sm" style={{ width: "100%" }} onClick={submit}><Icon name="check" size={13} /> Record assumptions for review</button>}
      <div className="muted" style={{ fontSize: 10.5, marginTop: 6, lineHeight: 1.4 }}>Exploring is free. Submitting snapshots these levers as a governed assumption set and creates a checker task.</div>
      <button className="btn btn-ghost btn-sm" style={{ width: "100%", marginTop: 8 }} onClick={onReset}><Icon name="refresh" size={13} /> Clear stress · restore baseline</button>
    </aside>
  );
}
function DockSlider({ label, cell, v, unit, min, max, step, onChange }) {
  return (
    <div>
      <div className="between" style={{ marginBottom: 5 }}><span style={{ fontSize: 12, fontWeight: 600 }}>{label}</span><span className="chip chip-indigo" style={{ fontSize: 10.5 }}>{v}{unit}</span></div>
      <input type="range" className="lev-slider" min={min} max={max} step={step} value={v} onChange={e => onChange(e.target.value)} />
      <div className="muted" style={{ fontSize: 10.5, marginTop: 3 }}>drives cell {cell}</div>
    </div>
  );
}

window.CapitalTemplate = CapitalTemplate;
