// FPnAPage — window.FPnAPage — the FP&A Command Center.
//
// Variance analysis, an EBITDA bridge, a rolling full-year forecast, sensitivity
// analysis and banking / credit intelligence — all computed from the real GL.
//
// HONEST DATA SOURCING: section totals come from K.catBreakdownWindow over the
// taxonomy sections (revenue / cogs / opex / interest) — NOT from hard-coded
// category slugs, which do not exist in this schema. EBITDA is gp − opex (the
// plHistory `ebitda` key is actually net income). Balance-sheet ratios read
// data.bs (current_assets / current_liabilities / inventory / total_liabilities).
// data.budget is optional — when absent, variance degrades honestly to Actual vs
// Prior Year rather than inventing a budget.

(function () {
  const h = React.createElement;
  const { useState, useMemo } = React;

  const info = (metric) => (window.MetricTooltip ? h(window.MetricTooltip, { metric }) : null);
  const withInfo = (label, metric) => h("span", { style: { display: "inline-flex", alignItems: "center", gap: 0 } }, label, info(metric));

  // ── model ───────────────────────────────────────────────────────────────────
  function buildModel(K, txns, profile, plH, bs, range, cmpRange, ltmRange, budget) {
    const sc = (a) => a.reduce((s, r) => s + r.cur, 0), sp = (a) => a.reduce((s, r) => s + r.prior, 0);
    const rev = K.catBreakdownWindow(txns, profile, ["revenue"], range, cmpRange);
    const cogs = K.catBreakdownWindow(txns, profile, ["cogs"], range, cmpRange);
    const opex = K.catBreakdownWindow(txns, profile, ["opex"], range, cmpRange);
    const T = { rev: sc(rev), cogs: sc(cogs), opex: sc(opex), revP: sp(rev), cogsP: sp(cogs), opexP: sp(opex) };
    T.gp = T.rev - T.cogs; T.gpP = T.revP - T.cogsP;
    T.ebitda = T.gp - T.opex; T.ebitdaP = T.gpP - T.opexP;
    T.gm = T.rev ? T.gp / T.rev : null; T.gmP = T.revP ? T.gpP / T.revP : null;

    const monthsElapsed = Math.max(1, (range.end.getFullYear() - range.start.getFullYear()) * 12 + (range.end.getMonth() - range.start.getMonth()) + 1);
    const monthsRemaining = Math.max(0, 12 - monthsElapsed);
    const rr = { rev: T.rev / monthsElapsed, cogs: T.cogs / monthsElapsed, opex: T.opex / monthsElapsed };
    const projection = {
      revenue: T.rev + rr.rev * monthsRemaining,
      grossProfit: T.gp + (rr.rev - rr.cogs) * monthsRemaining,
      ebitda: T.ebitda + (rr.rev - rr.cogs - rr.opex) * monthsRemaining,
      opex: T.opex + rr.opex * monthsRemaining,
    };

    // Exactly-reconciling EBITDA bridge (prior-yr → current):
    //   revEffect + marginEffect = ΔGrossProfit ; −ΔOPEX closes to current EBITDA.
    const hasComparison = T.revP > 0 || T.ebitdaP !== 0;
    let revEffect = 0, marginEffect = 0;
    if (T.revP > 0) {
      revEffect = (T.rev - T.revP) * (T.gpP / T.revP);
      marginEffect = ((T.rev ? T.gp / T.rev : 0) - (T.gpP / T.revP)) * T.rev;
    } else {
      revEffect = T.gp - T.gpP; marginEffect = 0;
    }
    const opexEffect = -(T.opex - T.opexP);
    const bridge = [
      { label: "Prior-Yr EBITDA", value: T.ebitdaP, type: "start" },
      { label: "Revenue growth", value: revEffect, type: revEffect >= 0 ? "positive" : "negative" },
      { label: "Margin change", value: marginEffect, type: marginEffect >= 0 ? "positive" : "negative" },
      { label: "OPEX change", value: opexEffect, type: opexEffect >= 0 ? "positive" : "negative" },
      { label: "Current EBITDA", value: T.ebitda, type: "end" },
    ];

    const sensitivity = {
      revUp5: T.rev * 0.05,
      revDn5: -(T.rev * 0.05),
      cogsBps100: T.rev * 0.01,
      opexAnnual: rr.opex * 12,
    };

    // Optional budget: only when data.budget carries window-level numbers.
    let bud = null;
    if (budget && typeof budget === "object") {
      const g = (k) => { const v = budget[k]; return (typeof v === "number" && isFinite(v)) ? v : null; };
      const bRev = g("revenue"), bCogs = g("cogs"), bOpex = g("opex"), bGp = g("gross_profit"), bEbitda = g("ebitda");
      if (bRev != null || bEbitda != null) {
        bud = { rev: bRev, cogs: bCogs, opex: bOpex, gp: bGp != null ? bGp : (bRev != null && bCogs != null ? bRev - bCogs : null), ebitda: bEbitda != null ? bEbitda : ((bGp != null || (bRev != null && bCogs != null)) && bOpex != null ? (bGp != null ? bGp : bRev - bCogs) - bOpex : null) };
      }
    }

    // ── Banking / credit ratios ───────────────────────────────────────────────
    let banking = null;
    if (bs) {
      const ebitdaLTM = (plH && plH.gp || []).slice(-12).reduce((a, b) => a + (Number(b) || 0), 0) - (plH && plH.opex || []).slice(-12).reduce((a, b) => a + (Number(b) || 0), 0);
      const interestLTM = ltmRange ? sc(K.catBreakdownWindow(txns, profile, ["interest"], ltmRange, null)) : 0;
      const ca = Number(bs.current_assets) || 0, cl = Number(bs.current_liabilities) || 0, inv = Number(bs.inventory) || 0, tl = Number(bs.total_liabilities) || 0;
      banking = {
        ebitdaLTM, interestLTM,
        dscr: interestLTM > 0 ? ebitdaLTM / interestLTM : null,
        currentRatio: cl > 0 ? ca / cl : null,
        quickRatio: cl > 0 ? (ca - inv) / cl : null,
        leverage: ebitdaLTM > 0 ? tl / ebitdaLTM : null,
        currentAssets: ca, currentLiabilities: cl, inventory: inv, totalLiabilities: tl,
        workingCapital: ca - cl,
      };
    }

    return { T, monthsElapsed, monthsRemaining, projection, bridge, sensitivity, hasComparison, budget: bud, banking };
  }

  // Banker-grade threshold classification.
  function band(metric, v) {
    if (v == null) return { dot: "⚪", color: "#6475a0", label: "not available" };
    const G = { dot: "🟢", color: "#059669" }, Y = { dot: "🟡", color: "#B45309" }, R = { dot: "🔴", color: "#DC2626" };
    if (metric === "dscr") return v >= 1.25 ? Object.assign({}, G, { label: "Healthy — meets typical 1.25× covenant" }) : v >= 1.0 ? Object.assign({}, Y, { label: "Watch — approaching covenant floor" }) : Object.assign({}, R, { label: "Below 1.0× — cannot cover debt service" });
    if (metric === "currentRatio") return v >= 2.0 ? Object.assign({}, G, { label: "Strong liquidity" }) : v >= 1.0 ? Object.assign({}, Y, { label: "Adequate — monitor working capital" }) : Object.assign({}, R, { label: "Below 1.0× — current liabilities exceed current assets" });
    if (metric === "quickRatio") return v >= 1.0 ? Object.assign({}, G, { label: "Healthy" }) : v >= 0.5 ? Object.assign({}, Y, { label: "Tight — limited quick liquidity" }) : Object.assign({}, R, { label: "Stressed — may struggle to meet short-term obligations" });
    if (metric === "leverage") return v <= 2.5 ? Object.assign({}, G, { label: "Conservative leverage" }) : v <= 4.0 ? Object.assign({}, Y, { label: "Moderate — typical for leveraged businesses" }) : Object.assign({}, R, { label: "High leverage — restrict new debt capacity" });
    return { dot: "⚪", color: "#6475a0", label: "" };
  }

  function Page(props) {
    const K = window.PerduraPageKit;
    if (!K) return h("div", { className: "pc-page" }, "Loading…");
    const { data, companyProfile, scopedCompanyId, globalPeriod } = props;
    const MONO = K.MONO, INK = K.INK, MUTE = K.MUTE, POS = K.POS, NEG = K.NEG, LINE = K.LINE;
    const M = (v) => K.moneyStr(v, { compact: true });
    const Mf = (v) => K.moneyStr(v);
    const pctS = (v) => (v == null ? "—" : (v * 100).toFixed(1) + "%");

    const txns = (data && data.txns) || [];
    const plH = (data && (data.plHistory || data.pl)) || { labels: [], revenue: [] };
    const bs = (data && data.bs) || null;
    const budget = (data && data.budget) || null;

    const anchor = K.anchorFromPlH(plH);
    const ps = K.usePeriodState("fpna", "ytd");
    const range = K.resolvePeriod(ps.mode, anchor, ps.custom);
    const cmpRange = K.comparePeriod(range, "prior_year");
    const ltmRange = K.resolvePeriod("ltm", anchor, null);

    const model = useMemo(() => buildModel(K, txns, companyProfile, plH, bs, range, cmpRange, ltmRange, budget),
      [txns, companyProfile, plH, bs, range, cmpRange, budget]);

    const [tab, setTab] = useState("variance");

    if (!txns.length) {
      return h(K.Shell, { hero: { eyebrow: "INTELLIGENCE", title: "FP&A Command Center", subtitle: "Variance, forecast, sensitivity and banking intelligence" } },
        h(K.Card, { title: "Awaiting general-ledger data" }, h("div", { style: { padding: 24, color: MUTE, fontSize: 13 } }, "Connect your accounting system or import a transaction feed to unlock FP&A analysis.")));
    }

    const T = model.T;
    const hero = {
      eyebrow: "INTELLIGENCE",
      title: "FP&A Command Center",
      subtitle: "Actual vs Prior Year · rolling forecast · sensitivity · banking — " + range.label + (model.budget ? " · budget loaded" : ""),
      controls: h(K.PeriodControls, Object.assign({}, ps, { showCompare: false })),
    };

    const TABS = [["variance", "📊 Variance"], ["bridge", "🌉 EBITDA Bridge"], ["forecast", "🔮 Rolling Forecast"], ["sensitivity", "🎚 Sensitivity"], ["banking", "🏦 Banking & Credit"]];
    const tabBar = h("div", { style: { display: "flex", gap: 4, borderBottom: "2px solid rgba(13,32,64,.08)", marginBottom: 22, overflowX: "auto" } },
      TABS.map(([id, label]) => h("button", { key: id, onClick: () => setTab(id), style: { padding: "10px 18px", fontSize: 12, fontWeight: 700, cursor: "pointer", border: "none", borderBottom: tab === id ? "3px solid #0d2040" : "3px solid transparent", background: "transparent", color: tab === id ? "#0d2040" : "#6475a0", whiteSpace: "nowrap" } }, label)));

    // ── Tab: Variance ─────────────────────────────────────────────────────────
    function varianceTab() {
      const hasBudget = !!model.budget;
      const rowsDef = [
        { key: "Revenue", metric: null, actual: T.rev, prior: T.revP, bud: hasBudget ? model.budget.rev : null, isCost: false },
        { key: "Gross Profit", metric: "Gross Margin", actual: T.gp, prior: T.gpP, bud: hasBudget ? model.budget.gp : null, isCost: false },
        { key: "EBITDA", metric: "EBITDA", actual: T.ebitda, prior: T.ebitdaP, bud: hasBudget ? model.budget.ebitda : null, isCost: false },
        { key: "OPEX", metric: "Working Capital", actual: T.opex, prior: T.opexP, bud: hasBudget ? model.budget.opex : null, isCost: true },
      ];
      const sig = (actual, ref, isCost) => {
        if (ref == null || ref === 0) return { dot: "⚪", color: MUTE };
        const fav = isCost ? actual <= ref : actual >= ref;
        const mag = Math.abs((actual - ref) / ref);
        return fav ? { dot: "🟢", color: POS } : (mag > 0.1 ? { dot: "🔴", color: NEG } : { dot: "🟡", color: "#B45309" });
      };
      const cell = (v, right) => h("td", { className: "num", style: { fontFamily: MONO, fontWeight: right ? 700 : 500, textAlign: "right" } }, Mf(v));
      const varCell = (actual, ref, isCost) => {
        if (ref == null) return h("td", { className: "num", style: { color: MUTE } }, "—");
        const d = actual - ref; const pctv = ref !== 0 ? d / Math.abs(ref) : null;
        const fav = isCost ? d <= 0 : d >= 0;
        return h("td", { className: "num", style: { fontFamily: MONO, fontWeight: 700, textAlign: "right", color: fav ? POS : NEG } }, (d >= 0 ? "+" : "−") + M(Math.abs(d)) + (pctv != null ? " (" + (pctv >= 0 ? "+" : "−") + Math.abs(pctv * 100).toFixed(1) + "%)" : ""));
      };
      const head = hasBudget
        ? h("tr", null, h("th", null, "Metric"), h("th", { className: "num" }, "Actual"), h("th", { className: "num" }, "Budget"), h("th", { className: "num" }, "vs Budget"), h("th", { className: "num" }, "Prior Yr"), h("th", { className: "num" }, "vs PY"), h("th", { className: "num" }, "Signal"))
        : h("tr", null, h("th", null, "Metric"), h("th", { className: "num" }, "Actual"), h("th", { className: "num" }, "Prior Yr"), h("th", { className: "num" }, "vs PY $"), h("th", { className: "num" }, "vs PY %"), h("th", { className: "num" }, "Signal"));
      const body = rowsDef.map((r) => {
        const ref = hasBudget ? r.bud : r.prior;
        const s = sig(r.actual, ref, r.isCost);
        const label = r.metric ? withInfo(r.key, r.metric) : r.key;
        const pyPct = r.prior && r.prior !== 0 ? (r.actual - r.prior) / Math.abs(r.prior) : null;
        if (hasBudget) {
          return h("tr", { key: r.key },
            h("td", { style: { fontWeight: 700, color: INK } }, label),
            cell(r.actual, true), cell(r.bud), varCell(r.actual, r.bud, r.isCost), cell(r.prior),
            h("td", { className: "num", style: { fontFamily: MONO, textAlign: "right", color: MUTE } }, pyPct != null ? (pyPct >= 0 ? "+" : "−") + Math.abs(pyPct * 100).toFixed(1) + "%" : "—"),
            h("td", { className: "num", title: s.label, style: { textAlign: "right" } }, s.dot));
        }
        return h("tr", { key: r.key },
          h("td", { style: { fontWeight: 700, color: INK } }, label),
          cell(r.actual, true), cell(r.prior), varCell(r.actual, r.prior, r.isCost),
          h("td", { className: "num", style: { fontFamily: MONO, textAlign: "right", color: MUTE } }, pyPct != null ? (pyPct >= 0 ? "+" : "−") + Math.abs(pyPct * 100).toFixed(1) + "%" : "—"),
          h("td", { className: "num", title: s.label, style: { textAlign: "right" } }, s.dot));
      });
      const banner = hasBudget ? null : h("div", { style: { background: "#eef2ff", border: "1px solid #c7d2fe", borderRadius: 10, padding: "10px 14px", marginBottom: 16, fontSize: 12, color: "#3730a3" } }, "No budget is loaded for this company — variance is shown against ", h("b", null, "Prior Year"), " (fully derived from the ledger). Load a budget to unlock Actual-vs-Budget columns.");
      const kpis = h("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(160px,1fr))", gap: 14, marginBottom: 20 } },
        h(K.Kpi, { label: "Revenue", value: M(T.rev), sub: range.label, accent: "#1C4ED8" }),
        h(K.Kpi, { label: "Gross Profit", value: M(T.gp), sub: pctS(T.gm) + " margin", accent: "#0891B2" }),
        h(K.Kpi, { label: "EBITDA", value: M(T.ebitda), sub: T.rev ? pctS(T.ebitda / T.rev) + " margin" : null, accent: "#059669" }),
        h(K.Kpi, { label: "OPEX", value: M(T.opex), sub: T.rev ? pctS(T.opex / T.rev) + " of revenue" : null, accent: "#DC2626" }));
      return h("div", null, kpis, banner,
        h(K.Card, { title: "Variance Analysis", sub: hasBudget ? "Actual vs Budget and Prior Year" : "Actual vs Prior Year · costs favourable when lower", padding: 0 },
          h("div", { style: { overflowX: "auto" } }, h("table", { className: "pa-table", style: { width: "100%" } }, h("thead", null, head), h("tbody", null, body)))));
    }

    // ── Tab: EBITDA Bridge ────────────────────────────────────────────────────
    function bridgeTab() {
      if (!model.hasComparison) return h(K.Card, { title: "EBITDA Bridge" }, h("div", { style: { padding: 20, color: MUTE, fontSize: 12.5 } }, "No prior-year window is available to bridge against."));
      return h("div", null,
        h(K.Card, { title: "EBITDA Bridge — Prior Year → Current", sub: "Revenue-growth and margin effects reconcile exactly to the gross-profit change; OPEX change closes to current EBITDA" },
          h(K.BridgeChart, { items: model.bridge }),
          h(K.KeyTakeaway, { text: "Prior-year EBITDA of " + Mf(T.ebitdaP) + " moved to " + Mf(T.ebitda) + " — revenue growth contributed " + Mf(model.bridge[1].value) + ", margin " + (model.bridge[2].value >= 0 ? "added " : "cost ") + Mf(Math.abs(model.bridge[2].value)) + ", and OPEX " + (model.bridge[3].value >= 0 ? "fell by " : "rose by ") + Mf(Math.abs(model.bridge[3].value)) + "." })));
    }

    // ── Tab: Rolling Forecast ─────────────────────────────────────────────────
    function forecastTab() {
      const cashData = data && data.cash;
      const cashYE = cashData && typeof cashData.endCash === "number" ? cashData.endCash : null;
      const runway = cashData && typeof cashData.runwayDays === "number" ? cashData.runwayDays : null;
      const projRow = (label, ytd, proj, metric) => h("tr", { key: label },
        h("td", { style: { fontWeight: 700, color: INK } }, metric ? withInfo(label, metric) : label),
        h("td", { className: "num", style: { fontFamily: MONO } }, Mf(ytd)),
        h("td", { className: "num", style: { fontFamily: MONO, fontWeight: 800, color: "#1C4ED8" } }, Mf(proj)));
      const table = h("table", { className: "pa-table", style: { width: "100%" } },
        h("thead", null, h("tr", null, h("th", null, "Metric"), h("th", { className: "num" }, "YTD Actual (" + model.monthsElapsed + " mo)"), h("th", { className: "num" }, "Full-Year Projection"))),
        h("tbody", null,
          projRow("Revenue", T.rev, model.projection.revenue),
          projRow("Gross Profit", T.gp, model.projection.grossProfit, "Gross Margin"),
          projRow("EBITDA", T.ebitda, model.projection.ebitda, "EBITDA"),
          projRow("OPEX", T.opex, model.projection.opex)));
      const cashCard = h(K.Card, { title: "Projected Cash at Year-End" },
        cashYE != null
          ? h("div", { style: { padding: "6px 4px" } },
              h("div", { style: { fontSize: 30, fontWeight: 800, fontFamily: MONO, color: cashYE >= 0 ? "#059669" : "#DC2626" } }, Mf(cashYE)),
              h("div", { style: { fontSize: 12, color: MUTE, marginTop: 4 } }, "90-day operating-cash projection" + (runway != null && runway < 900 ? " · ~" + runway + " days runway at current burn" : "")))
          : h("div", { style: { padding: 16, color: MUTE, fontSize: 12.5 } }, "Cash projection appears once a cash-account feed is connected."));
      return h("div", null,
        h(K.Card, { title: "Rolling Full-Year Forecast", sub: model.monthsElapsed + " months elapsed · projected on the YTD run-rate for the remaining " + model.monthsRemaining + " months", padding: 0 },
          h("div", { style: { overflowX: "auto" } }, table)),
        h("div", { style: { marginTop: 16 } }, cashCard),
        h("div", { style: { marginTop: 12, fontSize: 11, color: MUTE, lineHeight: 1.6 } }, "Projection is a straight-line YTD run-rate — it does not account for seasonality, pipeline or one-off items. Treat it as a directional trajectory, not a plan."));
    }

    // ── Tab: Sensitivity ──────────────────────────────────────────────────────
    function sensitivityTab() {
      const s = model.sensitivity;
      const row = (label, val, note, good) => h("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "13px 16px", border: "1px solid " + LINE, borderRadius: 9, marginBottom: 10 } },
        h("div", null, h("div", { style: { fontSize: 13, fontWeight: 700, color: INK } }, label), h("div", { style: { fontSize: 11, color: MUTE, marginTop: 2 } }, note)),
        h("div", { style: { fontSize: 18, fontWeight: 800, fontFamily: MONO, color: good == null ? INK : good ? POS : NEG } }, (val >= 0 ? "+" : "−") + M(Math.abs(val))));
      return h("div", null,
        h(K.Card, { title: "Sensitivity Analysis", sub: "How EBITDA and costs move with the key drivers, from your current run-rate" },
          row("Revenue +5%", s.revUp5, "EBITDA impact, holding cost structure constant", true),
          row("Revenue −5%", s.revDn5, "EBITDA impact, holding cost structure constant", false),
          row("COGS +100 bps", -s.cogsBps100, "EBITDA impact of a 1-point rise in COGS % of revenue", false),
          row("COGS −100 bps", s.cogsBps100, "EBITDA impact of a 1-point fall in COGS % of revenue", true),
          h("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "13px 16px", border: "1px solid " + LINE, borderRadius: 9, marginTop: 4 } },
            h("div", null, h("div", { style: { fontSize: 13, fontWeight: 700, color: INK } }, "OPEX at current run-rate"), h("div", { style: { fontSize: 11, color: MUTE, marginTop: 2 } }, "Annualised from the YTD monthly average")),
            h("div", { style: { fontSize: 18, fontWeight: 800, fontFamily: MONO, color: INK } }, Mf(s.opexAnnual)))));
    }

    // ── Tab: Banking & Credit ─────────────────────────────────────────────────
    function bankingTab() {
      const b = model.banking;
      if (!b) return h(K.Card, { title: "Banking & Credit Intelligence" }, h("div", { style: { padding: 22, color: MUTE, fontSize: 13, lineHeight: 1.7 } }, "Liquidity and leverage ratios need a balance sheet. No balance-sheet accounts were found in the general ledger for this company — connect a full chart of accounts (assets and liabilities) to unlock DSCR, current ratio, quick ratio and leverage."));
      const gauge = (title, metric, val, suffix) => {
        const bd = band(metric, val);
        return h("div", { style: { border: "1px solid " + LINE, borderRadius: 11, padding: 16 } },
          h("div", { style: { display: "flex", alignItems: "center", marginBottom: 8 } }, h("span", { style: { fontSize: 11, fontWeight: 700, color: MUTE, textTransform: "uppercase", letterSpacing: 0.5 } }, title), info(metric === "dscr" ? "DSCR" : metric === "currentRatio" ? "Current Ratio" : metric === "quickRatio" ? "Quick Ratio" : "Leverage")),
          h("div", { style: { fontSize: 30, fontWeight: 800, fontFamily: MONO, color: bd.color } }, val == null ? "—" : (val.toFixed(2) + (suffix || ""))),
          h("div", { style: { fontSize: 11.5, color: bd.color, fontWeight: 600, marginTop: 4, lineHeight: 1.4 } }, bd.dot + " " + bd.label));
      };
      const cards = h("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(210px,1fr))", gap: 14, marginBottom: 18 } },
        gauge("DSCR (interest-coverage proxy)", "dscr", b.dscr, "×"),
        gauge("Current Ratio", "currentRatio", b.currentRatio, "×"),
        gauge("Quick Ratio", "quickRatio", b.quickRatio, "×"),
        gauge("Leverage", "leverage", b.leverage, "×"));
      // Debt-capacity headroom to a 4.0× leverage ceiling (honest, informational).
      const capacity = (b.ebitdaLTM > 0) ? Math.max(0, 4.0 * b.ebitdaLTM - b.totalLiabilities) : null;
      const dscrTxt = b.dscr != null ? ("Your DSCR of " + b.dscr.toFixed(2) + "× (EBITDA ÷ interest) " + (b.dscr >= 1.25 ? "clears the typical 1.25× covenant floor with headroom." : b.dscr >= 1.0 ? "is above 1.0× but below the usual 1.25× covenant — watch it." : "is below 1.0× — operating cash isn't covering interest.")) : "Interest expense isn't posting to the ledger, so a coverage ratio can't be computed.";
      const levTxt = b.leverage != null ? (" Leverage sits at " + b.leverage.toFixed(1) + "× EBITDA (total liabilities basis)" + (capacity != null && capacity > 0 ? "; there is roughly " + Mf(capacity) + " of additional debt headroom before a 4.0× ceiling." : "; leverage is at or above a 4.0× ceiling, so new debt capacity is limited.")) : "";
      const note = h("div", { style: { background: "linear-gradient(135deg, rgba(13,32,64,.04) 0%, rgba(28,78,216,.04) 100%)", border: "1px solid rgba(13,32,64,.12)", borderLeft: "4px solid #1C4ED8", borderRadius: 10, padding: "16px 18px" } },
        h("div", { style: { fontSize: 10, fontWeight: 800, color: "#1C4ED8", letterSpacing: ".1em", textTransform: "uppercase", marginBottom: 8 } }, "🏦 CFO Banking Note"),
        h("div", { style: { fontSize: 13, color: "#1a2540", lineHeight: 1.7 } }, dscrTxt + levTxt),
        h("div", { style: { fontSize: 11, color: MUTE, marginTop: 10, lineHeight: 1.5 } }, "DSCR here uses interest expense as the debt-service proxy — the GL does not carry a principal-amortisation schedule, so true DSCR (interest + principal) may be lower. Leverage uses total liabilities as the debt basis. For covenant work, reconcile to your loan agreement."));
      return h("div", null, cards, note);
    }

    const body = tab === "variance" ? varianceTab()
      : tab === "bridge" ? bridgeTab()
      : tab === "forecast" ? forecastTab()
      : tab === "sensitivity" ? sensitivityTab()
      : bankingTab();

    const cfoNotes = window.CFONotes ? h(window.CFONotes, { pageType: "fpna", tenantId: scopedCompanyId, periodStart: globalPeriod && globalPeriod.resolved && globalPeriod.resolved.startDate, periodEnd: globalPeriod && globalPeriod.resolved && globalPeriod.resolved.endDate }) : null;

    return h(K.Shell, { hero }, tabBar, body, cfoNotes);
  }

  window.FPnAPage = Page;
})();
