/* global React, Icon, StatusChip, PageHeader, Banner, etb */
const { useState: useStateALM } = React;

/* ============================================================
   ALM / Liquidity — Maturity (time-band) gap ladder
   Contractual inflows vs outflows per band → net gap → cumulative gap.
   Stress = deposit early-withdrawal pulls non-maturity deposits into the
   short bands (behavioral run-off), widening the near-term negative gap.
   ETB millions · internal/synthetic
   ============================================================ */
const BANDS = ["≤7d", "8d–1m", "1–3m", "3–6m", "6–12m", "1–3y", ">3y"];
// inflows (assets maturing) and outflows (liabilities maturing) per band
const INFLOW = [9200, 7400, 11800, 9600, 12400, 21000, 28600];
const OUTFLOW_BASE = [6800, 8200, 9400, 8800, 9200, 7400, 4200];
// portion of non-maturity deposits assumed in >1y bands that runs to short bands under stress
const NMD_LONG = [0, 0, 0, 0, 0, 9000, 6000];   // sits in 1-3y / >3y at base (behavioral)

function ladder(runoff) {
  // runoff% of NMD_LONG shifts into the ≤7d and 8d-1m bands
  const shift = NMD_LONG.map(v => v * runoff / 100);
  const movedTotal = shift.reduce((a, b) => a + b, 0);
  const out = OUTFLOW_BASE.map((v, i) => {
    let x = v - shift[i];                 // leaves the long bands
    if (i === 0) x += movedTotal * 0.6;   // 60% hits ≤7d
    if (i === 1) x += movedTotal * 0.4;   // 40% hits 8d–1m
    return x;
  });
  const net = INFLOW.map((v, i) => v - out[i]);
  let c = 0; const cum = net.map(n => (c += n));
  return { out, net, cum };
}
const BASE = ladder(0);
const ALMSEV = [{ name: "Mild", r: 15 }, { name: "Moderate", r: 30 }, { name: "Severe", r: 55 }, { name: "Extreme", r: 85 }];
// survival horizon: first band where cumulative gap goes negative (else >3y)
function survival(cum) { const i = cum.findIndex(v => v < 0); return i === -1 ? ">12m" : BANDS[i]; }

const ALM_HELP = {
  title: "ALM / Liquidity · Maturity ladder",
  purpose: "The structural liquidity gap. Assets and liabilities are slotted into time bands; the net and cumulative gap show where funding pressure builds. Stress pulls non-maturity deposits into the near bands (behavioral run-off).",
  first: "Read the cumulative-gap row — the first negative band is the survival horizon. Click Stress test to add severity columns.",
  terms: [["Time band", "Residual-maturity bucket."], ["Net gap", "Inflows − outflows in a band."], ["Cumulative gap", "Running sum across bands."], ["Survival horizon", "First band where cumulative gap turns negative."]],
  next: ["Click Stress test for the ladder under each run-off severity.", "Tune the run-off lever; the Custom row recomputes live.", "A near-term negative gap hands off to Recovery."],
  connections: ["Balances reconcile to the deposits & loans sources.", "Behavioral assumptions need bank-policy sign-off.", "Feeds survival-horizon monitoring."],
  guardrail: "Internal ALM workpaper. Behavioral assumptions are provisional until policy sign-off; stress is analysis-only.",
};

function ALMSheet({ go, info }) {
  const [stress, setStress] = useStateALM(false);
  const [mode, setMode] = useStateALM("Custom");
  const [run, setRun] = useStateALM(55);
  const live = ladder(run);
  const breach = live.cum.findIndex(v => v < 0) !== -1 && live.cum.findIndex(v => v < 0) <= 2;
  const f = v => (v < 0 ? "(" + etb(Math.abs(Math.round(v))) + ")" : etb(Math.round(v)));

  // a row that renders band cells; in stress we instead show severity columns for the summary rows only
  const BandRow = ({ no, label, vals, kind, neg }) => (
    <tr className={kind || "xl-item"}>
      <td className="xl-no">{no}</td><td className="xl-label">{label}</td>
      {vals.map((v, i) => <td key={i} className="xl-amt tnum" style={{ color: (neg && v < 0) ? "var(--red)" : undefined }}>{f(v)}</td>)}
    </tr>
  );

  return (
    <div className="main-inner">
      <PageHeader eyebrow="Prudential Risk · Liquidity" title="ALM / Liquidity" onInfo={() => info(ALM_HELP)}
        right={<button className={"btn btn-sm " + (stress ? "btn-dark" : "btn-ghost")} onClick={() => setStress(!stress)}><Icon name="flask" size={15} /> {stress ? "Stress on" : "Stress test"}</button>} />

      <div style={{ marginBottom: 14 }}><Banner kind="amber" icon="alert">Behavioral assumptions (non-maturity deposit split) are pending bank-policy sign-off — the ladder uses contractual maturities at base.</Banner></div>

      {stress && <div className="banner banner-indigo mb12" style={{ alignItems: "center", padding: "11px 15px" }}>
        <Icon name="flask" size={18} className="ic" /><div className="grow"><b>Deposit early-withdrawal overlay</b> · pulls term deposits into the near bands · analysis-only</div><span className="chip chip-indigo">survival horizon</span>
      </div>}

      <div style={{ display: "flex", gap: 16, alignItems: "flex-start" }}>
        <div className="grow" style={{ minWidth: 0 }}>
          {/* the maturity ladder — bands as columns (always shown) */}
          <div className="xl-wrap mb12">
            <table className="xl xl-scroll">
              <colgroup><col style={{ width: 42 }} /><col style={{ width: 230 }} />{BANDS.map(b => <col key={b} style={{ width: 92 }} />)}</colgroup>
              <thead><tr><th className="xl-no"></th><th style={{ textAlign: "left" }}>Maturity Gap Ladder · ETB millions · residual maturity</th>{BANDS.map(b => <th key={b} className="xl-amt">{b}</th>)}</tr></thead>
              <tbody>
                <BandRow no="1" label="Inflows (assets maturing)" vals={INFLOW} />
                <BandRow no="2" label="Outflows (contractual)" vals={OUTFLOW_BASE} />
                <BandRow no="3" label="Net gap (contractual)" vals={BASE.net} kind="xl-sub" neg />
                {stress && <BandRow no="4" label="Outflows (stressed run-off)" vals={live.out} />}
                {stress && <BandRow no="5" label="Net gap (stressed)" vals={live.net} kind="xl-sub" neg />}
                <tr className="xl-orange">
                  <td className="xl-no"></td><td className="xl-label">Cumulative gap{stress ? " (stressed)" : ""}</td>
                  {(stress ? live.cum : BASE.cum).map((v, i) => <td key={i} className="xl-amt tnum" style={{ color: v < 0 ? "var(--red)" : "var(--green-ink)", fontWeight: 800 }}>{f(v)}</td>)}
                </tr>
                {stress && <tr className="xl-sub"><td className="xl-no"></td><td className="xl-label">Survival horizon — base <b>{survival(BASE.cum)}</b> → stressed <b style={{ color: breach ? "var(--red)" : "var(--indigo)" }}>{survival(live.cum)}</b></td><td className="xl-amt" colSpan={BANDS.length}></td></tr>}
              </tbody>
            </table>
          </div>

          {stress && <div className="mt12"><Banner kind={breach ? "red" : "indigo"} icon={breach ? "alert" : "flask"}>
            {breach ? <span><b>Near-term liquidity gap turns negative under this run-off.</b> Survival horizon shortens into the first months — hand to Recovery to record contingency funding actions.</span>
              : <span>Severity columns pull term deposits into the near bands. The <b style={{ color: "var(--indigo)" }}>Custom</b> column is your own run-off — tune it in the panel.</span>}
          </Banner></div>}
        </div>

        {stress && <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" }}>Run-off controls</b></span><span className="chip chip-indigo">Analysis-only</span></div>
          <div className="seg-ctl" style={{ width: "100%", marginBottom: 14 }}>{[["Presets", "Presets"], ["Custom", "Custom"]].map(([l, k]) => <button key={k} className={mode === k ? "on" : ""} style={{ flex: 1 }} onClick={() => setMode(k)}>{l}</button>)}</div>
          {mode === "Presets" && <div><div className="dock-label">Scenario severity</div><div className="seg-ctl" style={{ width: "100%" }}>{ALMSEV.map((s, i) => <button key={s.name} className={run === s.r ? "on" : ""} style={{ flex: 1, padding: "6px 2px" }} onClick={() => setRun(s.r)}>{s.name === "Moderate" ? "Mod" : s.name}</button>)}</div><div className="muted" style={{ fontSize: 11.5, marginTop: 8 }}>Sets term-deposit early-withdrawal to NBE's named bands.</div></div>}
          {mode === "Custom" && <div><div className="between" style={{ marginBottom: 5 }}><span style={{ fontSize: 12, fontWeight: 600 }}>Term-deposit early withdrawal</span><span className="chip chip-indigo" style={{ fontSize: 10.5 }}>{run}%</span></div><input type="range" className="lev-slider" min={0} max={100} step={5} value={run} onChange={e => setRun(+e.target.value)} /><div className="muted" style={{ fontSize: 10.5, marginTop: 3 }}>shifts long-dated deposits into the near bands</div></div>}
          <hr className="hr" style={{ margin: "16px 0" }} />
          <div className="dock-label">Survival horizon (stressed)</div>
          <div className="big-num tnum" style={{ fontSize: 26, color: breach ? "var(--red)" : "var(--green-ink)", marginTop: 2 }}>{survival(live.cum)}</div>
          <div className="muted" style={{ fontSize: 11.5, marginTop: 4 }}>≤7d cumulative gap {f(live.cum[0])}</div>
          {breach
            ? <button className="btn btn-dark btn-sm" style={{ width: "100%", marginTop: 12 }} onClick={() => go("recovery")}>Send to Recovery <Icon name="arrowR" size={13} /></button>
            : <div className="chip chip-green chip-lg" style={{ marginTop: 12 }}><span className="dot" />Near-term gap positive</div>}
          <button className="btn btn-ghost btn-sm" style={{ width: "100%", marginTop: 8 }} onClick={() => setRun(0)}><Icon name="refresh" size={13} /> Clear stress · restore baseline</button>
        </aside>}
      </div>
    </div>
  );
}
window.ALMSheet = ALMSheet;
