// CFOBriefingPage (weekly/monthly CFO digest) — window.CFOBriefingPage
// The Monday-morning read: everything that matters this period in ~2 minutes.
// Sections: AI executive summary (cfo-synthesis what_matters_now), what changed,
// open exceptions (cfo-synthesis exceptions_inbox), a period metrics snapshot,
// action items (localStorage), and a coming-up calendar (AP due dates + manual).
// Every figure derives from live `data` (GL txns + plHistory + bs) and Supabase
// subledger queries. No hardcoded business names or amounts. Built on PerduraPageKit.

(function () {
  const { useState, useEffect, useMemo } = React;
  const h = React.createElement;
  const MON = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
  const fmtD = (d) => d ? new Date(d).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }) : "—";
  const fmtShort = (d) => d ? new Date(d).toLocaleDateString("en-US", { month: "short", day: "numeric" }) : "—";

  const lsGet = (k, d) => { try { const v = localStorage.getItem(k); return v == null ? d : JSON.parse(v); } catch (e) { return d; } };
  const lsSet = (k, v) => { try { localStorage.setItem(k, JSON.stringify(v)); } catch (e) { /* ignore */ } };

  function Page(props) {
    const K = window.PerduraPageKit;
    if (!K) return h("div", { className: "pc-page" }, "Loading…");
    const { data, companyProfile, scopedCompanyId, setPage } = props;
    const money = (v) => K.moneyStr(v);
    const M = (v) => K.moneyStr(v, { compact: true });
    const nav = (p) => (setPage ? setPage(p) : (window.__perduraSetPage && window.__perduraSetPage(p)));
    const tenantId = scopedCompanyId || (companyProfile && companyProfile.id) || null;

    const [tab, setTab] = useState("week"); // week | month | last_month | custom
    const [custom, setCustom] = useState({ start: "", end: "" });
    const [ai, setAi] = useState({ status: "idle", summary: null, ts: null });
    const [exc, setExc] = useState({ status: "idle", items: [] });
    const [nonce, setNonce] = useState(0);
    const [apDue, setApDue] = useState(null);
    const [wc, setWc] = useState(null);
    const [actions, setActions] = useState([]);
    const [events, setEvents] = useState([]);
    const [newAction, setNewAction] = useState("");
    const [newEvent, setNewEvent] = useState({ date: "", text: "" });

    const txns = (data && data.txns) || [];
    const plH = (data && (data.plHistory || data.pl)) || null;
    const bs = data && data.bs;
    const hasData = !!(data && plH && Array.isArray(plH.revenue) && plH.revenue.length);

    // Dataset "today" = latest txn date (fixtures dated in the past behave sanely).
    const anchor = useMemo(() => {
      let mx = 0; for (const t of txns) { const d = t.posted_date ? +new Date(t.posted_date) : 0; if (d > mx) mx = d; }
      return mx ? new Date(mx) : new Date();
    }, [txns]);

    // ── Period windows (current / prior / YoY) for the active tab ───────────────
    const windows = useMemo(() => {
      const a = anchor, y = a.getFullYear(), m = a.getMonth();
      const shiftDays = (r, days) => ({ start: new Date(+r.start + days * 86400000), end: new Date(+r.end + days * 86400000) });
      const monthR = (yy, mm) => ({ start: new Date(yy, mm, 1), end: new Date(yy, mm + 1, 0) });
      if (tab === "week") {
        const dow = (a.getDay() + 6) % 7; // Monday = 0
        const start = new Date(a); start.setDate(a.getDate() - dow); start.setHours(0, 0, 0, 0);
        const cur = { start, end: a, label: "Week of " + fmtD(start) };
        return { cur, prior: Object.assign(shiftDays(cur, -7), { label: "prior week" }), yoy: Object.assign(shiftDays(cur, -364), { label: "same week last year" }), unit: "week" };
      }
      if (tab === "last_month") {
        const cur = Object.assign(monthR(y, m - 1), { label: MON[(m + 11) % 12] + " " + (m - 1 < 0 ? y - 1 : y) });
        return { cur, prior: Object.assign(monthR(y, m - 2), { label: "prior month" }), yoy: Object.assign(monthR(y - 1, m - 1), { label: "same month last year" }), unit: "month" };
      }
      if (tab === "custom" && custom.start) {
        const start = new Date(custom.start), end = custom.end ? new Date(custom.end) : a;
        const len = Math.max(1, Math.round((end - start) / 86400000));
        const cur = { start, end, label: fmtD(start) + " – " + fmtD(end) };
        return { cur, prior: Object.assign(shiftDays(cur, -(len + 1)), { label: "prior period" }), yoy: Object.assign(shiftDays(cur, -365), { label: "same period last year" }), unit: "custom" };
      }
      // this month
      const cur = Object.assign({ start: new Date(y, m, 1), end: a }, { label: MON[m] + " " + y });
      return { cur, prior: Object.assign(monthR(y, m - 1), { label: "prior month" }), yoy: Object.assign(monthR(y - 1, m), { label: "same month last year" }), unit: "month" };
    }, [tab, anchor, custom]);

    // Section totals (revenue / cogs / opex) over a window pair via taxonomy sections.
    const totals = (range, cmpRange) => {
      const sc = (arr) => arr.reduce((s, r) => s + r.cur, 0), sp = (arr) => arr.reduce((s, r) => s + r.prior, 0);
      const rev = K.catBreakdownWindow(txns, companyProfile, ["revenue"], range, cmpRange);
      const cogs = K.catBreakdownWindow(txns, companyProfile, ["cogs"], range, cmpRange);
      const opex = K.catBreakdownWindow(txns, companyProfile, ["opex"], range, cmpRange);
      const r = { rev: sc(rev), cogs: sc(cogs), opex: sc(opex), revP: sp(rev), cogsP: sp(cogs), opexP: sp(opex) };
      r.gp = r.rev - r.cogs; r.gpP = r.revP - r.cogsP;
      r.ebitda = r.gp - r.opex; r.ebitdaP = r.gpP - r.opexP;
      r.gm = r.rev ? r.gp / r.rev * 100 : null; r.gmP = r.revP ? r.gpP / r.revP * 100 : null;
      return r;
    };
    const cur = useMemo(() => totals(windows.cur, windows.prior), [txns, companyProfile, windows]);
    const yoy = useMemo(() => totals(windows.cur, windows.yoy), [txns, companyProfile, windows]);

    // LTM revenue/cogs for DSO/DPO.
    const ltm = useMemo(() => {
      const rev = (plH && plH.revenue || []).slice(-12).reduce((a, b) => a + (Number(b) || 0), 0);
      const cogs = (plH && plH.cogs || []).slice(-12).reduce((a, b) => a + (Number(b) || 0), 0);
      return { rev: rev > 0 ? rev : null, cogs: cogs > 0 ? cogs : null };
    }, [plH]);
    const arBal = bs ? bs.accounts_receivable : null, apBal = bs ? bs.accounts_payable : null;
    const dso = (arBal != null && ltm.rev) ? Math.round(arBal / (ltm.rev / 365)) : null;
    const dpo = (apBal != null && ltm.cogs) ? Math.round(apBal / (ltm.cogs / 365)) : null;
    const cashNow = bs ? bs.cash : (data && data.cash ? data.cash.endCash : null);

    // Prior-period DSO/DPO from working-capital snapshots (honest — only if stored).
    const wcPrior = useMemo(() => {
      if (!wc || wc.length < 2) return { dso: null, dpo: null };
      const p = wc[wc.length - 2];
      return { dso: p.dso_days != null ? Number(p.dso_days) : null, dpo: p.dpo_days != null ? Number(p.dpo_days) : null };
    }, [wc]);

    // ── Supabase: AP due dates (coming up) + WC snapshots (prior DSO/DPO) ────────
    useEffect(() => {
      let alive = true;
      const db = window.supabaseClient;
      if (!db || !scopedCompanyId) { setApDue([]); setWc([]); return; }
      db.from("ap_bills").select("bill_no,vendor_name,due_date,open_balance").eq("company_id", scopedCompanyId)
        .gt("open_balance", 0).order("due_date", { ascending: true }).limit(200)
        .then(({ data: d }) => { if (alive) setApDue(Array.isArray(d) ? d : []); });
      const cutoff = new Date(); cutoff.setMonth(cutoff.getMonth() - 16);
      db.from("working_capital_snapshots").select("period_end,dso_days,dpo_days").eq("company_id", scopedCompanyId)
        .gte("period_end", cutoff.toISOString().slice(0, 10)).order("period_end", { ascending: true }).limit(2000)
        .then(({ data: d }) => { if (alive) setWc(Array.isArray(d) ? d : []); });
      return () => { alive = false; };
    }, [scopedCompanyId]);

    // ── Action items + manual events (localStorage per company) ─────────────────
    const actKey = "perdura.briefing.actions." + (tenantId || "none");
    const evtKey = "perdura.briefing.events." + (tenantId || "none");
    useEffect(() => { setActions(lsGet(actKey, [])); setEvents(lsGet(evtKey, [])); }, [tenantId]);
    const saveActions = (a) => { setActions(a); lsSet(actKey, a); };
    const saveEvents = (e) => { setEvents(e); lsSet(evtKey, e); };

    // ── AI summary + exceptions (cfo-synthesis, cached per company+period) ───────
    const aiKey = "perdura.briefing.ai." + (tenantId || "none") + "." + tab;
    useEffect(() => {
      let alive = true;
      if (!nonce) { const c = lsGet(aiKey, null); if (c && c.summary) { setAi({ status: "done", summary: c.summary, ts: c.ts }); } }
      // No tenant / synthesis client → local fallbacks only; never call .fetch on undefined.
      if (!tenantId || !window.PerduraSynthesis || !window.PerduraSynthesis.fetch) {
        setExc({ status: "unavailable", items: [] });
        setAi((s) => ({ status: s.summary ? "done" : "unavailable", summary: s.summary, ts: s.ts }));
        return () => { alive = false; };
      }
      // Summary
      if (nonce || !(lsGet(aiKey, null) || {}).summary) {
        setAi((s) => ({ status: "loading", summary: s.summary, ts: s.ts }));
        window.PerduraSynthesis.fetch(tenantId, "what_matters_now").then((resp) => {
          if (!alive) return;
          if (!resp || resp.error) { setAi((s) => ({ status: "unavailable", summary: s.summary, ts: s.ts })); return; }
          const summary = resp.summary || ((resp.prioritized || []).slice(0, 3).map((it) => it.headline).filter(Boolean).join(" ")) || null;
          const ts = Date.now();
          setAi({ status: "done", summary, ts });
          lsSet(aiKey, { summary, ts });
        }).catch(() => { if (alive) setAi((s) => ({ status: "unavailable", summary: s.summary, ts: s.ts })); });
      }
      // Exceptions
      setExc((s) => ({ status: "loading", items: s.items }));
      window.PerduraSynthesis.fetch(tenantId, "exceptions_inbox").then((resp) => {
        if (!alive) return;
        const items = (resp && Array.isArray(resp.prioritized)) ? resp.prioritized : [];
        setExc({ status: resp && resp.error ? "unavailable" : "done", items });
      }).catch(() => { if (alive) setExc({ status: "unavailable", items: [] }); });
      return () => { alive = false; };
    }, [tenantId, tab, nonce]);

    // ── Empty state ─────────────────────────────────────────────────────────────
    if (!hasData) {
      return h(K.Shell, { hero: { eyebrow: "INTELLIGENCE", title: "CFO Briefing", subtitle: "Your Monday-morning digest" } },
        h(K.Card, { title: "Connect your accounting data to generate your briefing" },
          h("div", { style: { padding: 8, fontSize: 13.5, color: "#4a5680", lineHeight: 1.6 } },
            "The CFO Briefing summarizes what changed, what needs attention, and what's coming up — all from your live ledger. Connect a data source in ",
            h("a", { onClick: () => nav("settings_config"), style: { color: "#1C4ED8", cursor: "pointer", fontWeight: 600 } }, "Settings → Data Sources"), " to begin.")));
    }

    // ── Section 2: what changed ─────────────────────────────────────────────────
    const changeRow = (label, curV, priorV, opts) => {
      opts = opts || {};
      const fmt = opts.pct ? ((v) => v == null ? "—" : v.toFixed(1) + "%") : (opts.days ? ((v) => v == null ? "—" : Math.round(v) + " days") : money);
      let deltaStr, dirn;
      if (curV == null || priorV == null) { deltaStr = "—"; dirn = "flat"; }
      else if (opts.pct) { const bps = (curV - priorV) * 100; deltaStr = (bps >= 0 ? "+" : "") + bps.toFixed(0) + " bps"; dirn = Math.abs(bps) < 20 ? "flat" : bps >= 0 ? (opts.goodUp === false ? "dn" : "up") : (opts.goodUp === false ? "up" : "dn"); }
      else if (opts.days) { const dd = curV - priorV; deltaStr = (dd >= 0 ? "+" : "") + Math.round(dd) + " days"; dirn = Math.abs(dd) < 1 ? "flat" : dd >= 0 ? (opts.goodUp === false ? "dn" : "up") : (opts.goodUp === false ? "up" : "dn"); }
      else { const d = priorV !== 0 ? (curV - priorV) / Math.abs(priorV) * 100 : null; deltaStr = d == null ? "—" : (d >= 0 ? "+" : "") + d.toFixed(0) + "%"; dirn = d == null ? "flat" : Math.abs(d) < 2 ? "flat" : d >= 0 ? (opts.goodUp === false ? "dn" : "up") : (opts.goodUp === false ? "up" : "dn"); }
      const color = dirn === "up" ? "#059669" : dirn === "dn" ? "#DC2626" : "#6475a0";
      const arrow = dirn === "up" ? "▲" : dirn === "dn" ? "▼" : "—";
      return h("div", { key: label, style: { display: "grid", gridTemplateColumns: "20px 1fr auto auto", gap: 10, alignItems: "center", padding: "9px 4px", borderBottom: "1px solid rgba(13,32,64,.06)" } },
        h("span", { style: { color, fontWeight: 800, textAlign: "center" } }, arrow),
        h("span", { style: { fontSize: 12.5, fontWeight: 600, color: "#1a2540" } }, label),
        h("span", { style: { fontSize: 12, color: "#4a5680", fontFamily: K.MONO, textAlign: "right" } }, fmt(curV) + (priorV != null ? "  vs  " + fmt(priorV) : "")),
        h("span", { style: { fontSize: 12, fontWeight: 700, color, fontFamily: K.MONO, textAlign: "right", minWidth: 74 } }, deltaStr));
    };
    const whatChanged = h(K.Card, { title: "WHAT CHANGED THIS PERIOD", sub: windows.cur.label + " vs " + windows.prior.label },
      h("div", { style: { padding: "2px 0" } },
        changeRow("Revenue", cur.rev, cur.revP),
        changeRow("Gross margin", cur.gm, cur.gmP, { pct: true }),
        changeRow("Gross profit", cur.gp, cur.gpP),
        changeRow("EBITDA", cur.ebitda, cur.ebitdaP),
        changeRow("Operating expenses", cur.opex, cur.opexP, { goodUp: false }),
        cashNow != null ? changeRow("Cash on hand", cashNow, null) : null,
        dso != null ? changeRow("AR days (DSO)", dso, wcPrior.dso, { days: true, goodUp: false }) : null));

    // ── Section 3: open exceptions ──────────────────────────────────────────────
    const excItems = exc.items || [];
    const exceptionsCard = h(K.Card, { title: "OPEN EXCEPTIONS" + (excItems.length ? " (" + excItems.length + ")" : ""), sub: "Flagged by the intelligence layer · click to review" },
      excItems.length ? h("div", { style: { padding: "2px 0" } }, excItems.slice(0, 8).map((it, i) => {
        const sev = String(it.severity || "").toLowerCase();
        const dot = sev === "high" ? "🔴" : sev === "medium" ? "🟡" : sev === "low" ? "🟢" : "🟡";
        return h("div", { key: i, onClick: () => (it.drill_into && window.PerduraSynthesis ? window.PerduraSynthesis.navigateDrill(it.drill_into, setPage) : nav("exceptions")),
          style: { display: "flex", gap: 10, alignItems: "center", justifyContent: "space-between", padding: "9px 6px", borderBottom: "1px solid rgba(13,32,64,.05)", cursor: "pointer" } },
          h("div", { style: { display: "flex", gap: 9, alignItems: "flex-start" } },
            h("span", { style: { fontSize: 12, flexShrink: 0 } }, dot),
            h("div", null,
              h("span", { style: { fontSize: 12.5, fontWeight: 600, color: "#1a2540" } }, it.headline || "Exception"),
              it.estimated_dollar_impact ? h("span", { style: { fontSize: 11, color: "#6475a0", marginLeft: 6, fontFamily: K.MONO } }, "(" + money(Math.abs(it.estimated_dollar_impact)) + ")") : null)),
          h("span", { style: { fontSize: 11, color: "#1C4ED8", fontWeight: 600, whiteSpace: "nowrap" } }, "Review →"));
      }))
        : h("div", { className: "pa-card-body", style: { color: "#6475a0", fontSize: 12.5 } },
          exc.status === "loading" ? "Scanning for exceptions…" : "No open exceptions flagged this period. " + (exc.status === "unavailable" ? "(Intelligence layer unavailable.)" : "")));

    // ── Section 4: metrics snapshot ─────────────────────────────────────────────
    const snapRows = [
      { label: "Revenue", cur: cur.rev, prior: cur.revP, yoy: yoy.revP, fmt: money },
      { label: "Gross Margin", cur: cur.gm, prior: cur.gmP, yoy: yoy.gmP, pct: true },
      { label: "EBITDA", cur: cur.ebitda, prior: cur.ebitdaP, yoy: yoy.ebitdaP, fmt: money },
      { label: "Cash", cur: cashNow, prior: null, yoy: null, fmt: money },
      { label: "AR Days (DSO)", cur: dso, prior: wcPrior.dso, yoy: null, days: true },
      { label: "AP Days (DPO)", cur: dpo, prior: wcPrior.dpo, yoy: null, days: true },
    ];
    const chgCell = (c, base, opts) => {
      if (c == null || base == null) return h("span", { style: { color: "#94a3b8" } }, "—");
      if (opts.pct) { const bps = (c - base) * 100; return h("span", { style: { color: bps >= 0 ? "#059669" : "#DC2626", fontWeight: 700 } }, (bps >= 0 ? "+" : "") + bps.toFixed(0) + "bps"); }
      if (opts.days) { const dd = c - base; return h("span", { style: { color: dd <= 0 ? "#059669" : "#DC2626", fontWeight: 700 } }, (dd >= 0 ? "+" : "") + Math.round(dd) + "d"); }
      const d = base !== 0 ? (c - base) / Math.abs(base) * 100 : null; return h("span", { style: { color: d >= 0 ? "#059669" : "#DC2626", fontWeight: 700 } }, d == null ? "—" : (d >= 0 ? "+" : "") + d.toFixed(0) + "%");
    };
    const snapshot = h(K.Card, { title: "PERIOD SNAPSHOT", sub: windows.cur.label + " · vs prior period · vs prior year", padding: 0 },
      h("div", { style: { overflowX: "auto" } }, h("table", { className: "pa-table" },
        h("thead", null, h("tr", null, h("th", null, "Metric"), h("th", { className: "num" }, "This Period"), h("th", { className: "num" }, "Prior Period"), h("th", { className: "num" }, "Prior Yr"), h("th", { className: "num" }, "YoY"))),
        h("tbody", null, snapRows.map((r, i) => {
          const fmt = r.pct ? ((v) => v == null ? "—" : v.toFixed(1) + "%") : r.days ? ((v) => v == null ? "—" : Math.round(v) + "") : (r.fmt || money);
          return h("tr", { key: i },
            h("td", { style: { fontWeight: 600 } }, r.label),
            h("td", { className: "num", style: { fontWeight: 700 } }, fmt(r.cur)),
            h("td", { className: "num" }, fmt(r.prior)),
            h("td", { className: "num" }, fmt(r.yoy)),
            h("td", { className: "num" }, chgCell(r.cur, r.yoy != null ? r.yoy : r.prior, { pct: r.pct, days: r.days })));
        })))));

    // ── Section 5: action items ─────────────────────────────────────────────────
    const toggleAction = (id) => saveActions(actions.map((a) => a.id === id ? Object.assign({}, a, { done: !a.done }) : a));
    const removeAction = (id) => saveActions(actions.filter((a) => a.id !== id));
    const addAction = () => { const t = newAction.trim(); if (!t) return; saveActions(actions.concat([{ id: "a" + Date.now(), text: t, done: false }])); setNewAction(""); };
    const actionCard = h(K.Card, { title: "ACTION ITEMS", sub: "Persist locally · check off as you go" },
      h("div", { style: { padding: "2px 2px" } },
        actions.length ? actions.map((a) => h("div", { key: a.id, style: { display: "flex", gap: 10, alignItems: "center", padding: "7px 4px", borderBottom: "1px solid rgba(13,32,64,.05)" } },
          h("input", { type: "checkbox", checked: !!a.done, onChange: () => toggleAction(a.id), style: { width: 15, height: 15, cursor: "pointer" } }),
          h("span", { style: { flex: 1, fontSize: 12.5, color: a.done ? "#94a3b8" : "#1a2540", textDecoration: a.done ? "line-through" : "none" } }, a.text),
          h("button", { onClick: () => removeAction(a.id), title: "Remove", style: { background: "none", border: "none", color: "#94a3b8", cursor: "pointer", fontSize: 14 } }, "×")))
          : h("div", { style: { fontSize: 12, color: "#6475a0", padding: "6px 4px" } }, "No action items yet — add one below or seed from the exceptions above."),
        h("div", { style: { display: "flex", gap: 8, marginTop: 10 } },
          h("input", { value: newAction, onChange: (e) => setNewAction(e.target.value), onKeyDown: (e) => { if (e.key === "Enter") addAction(); }, placeholder: "Add an action item…", style: { flex: 1, padding: "7px 10px", border: "1px solid rgba(13,32,64,.15)", borderRadius: 7, fontSize: 12.5 } }),
          excItems.length ? h("button", { onClick: () => saveActions(actions.concat(excItems.slice(0, 5).filter((it) => it.headline).map((it) => ({ id: "a" + Date.now() + Math.round(performance.now()), text: it.headline, done: false })))), style: { background: "#EEF2FF", border: "1px solid rgba(28,78,216,.2)", color: "#1C4ED8", borderRadius: 7, padding: "7px 10px", fontSize: 11.5, fontWeight: 700, cursor: "pointer", whiteSpace: "nowrap" } }, "Seed from exceptions") : null,
          h("button", { onClick: addAction, style: { background: "#1C4ED8", border: "none", color: "#fff", borderRadius: 7, padding: "7px 14px", fontSize: 12, fontWeight: 700, cursor: "pointer" } }, "+ Add"))));

    // ── Section 6: coming up (AP due dates + manual events) ──────────────────────
    const upcomingBills = (apDue || []).filter((b) => { const d = +new Date(b.due_date); return isFinite(d) && d >= +anchor; })
      .map((b) => ({ date: +new Date(b.due_date), label: (b.vendor_name || "Vendor") + " " + (b.bill_no || "") + " due — " + money(Number(b.open_balance) || 0), kind: "ap" }));
    const manualEvents = (events || []).map((e) => ({ date: +new Date(e.date), label: e.text, kind: "manual", id: e.id }));
    const comingUp = upcomingBills.concat(manualEvents).filter((e) => isFinite(e.date)).sort((a, b) => a.date - b.date).slice(0, 12);
    const addEvent = () => { if (!newEvent.date || !newEvent.text.trim()) return; saveEvents(events.concat([{ id: "e" + Date.now(), date: newEvent.date, text: newEvent.text.trim() }])); setNewEvent({ date: "", text: "" }); };
    const comingCard = h(K.Card, { title: "COMING UP", sub: "Upcoming AP due dates (auto) + your manual entries" },
      h("div", { style: { padding: "2px 2px" } },
        comingUp.length ? comingUp.map((e, i) => h("div", { key: i, style: { display: "flex", gap: 12, alignItems: "center", padding: "7px 4px", borderBottom: "1px solid rgba(13,32,64,.05)" } },
          h("span", { style: { width: 58, fontSize: 11, fontWeight: 700, color: "#1C4ED8", fontFamily: K.MONO, flexShrink: 0 } }, fmtShort(e.date)),
          h("span", { style: { flex: 1, fontSize: 12.5, color: "#1a2540" } }, e.label),
          e.kind === "manual" ? h("button", { onClick: () => saveEvents(events.filter((x) => x.id !== e.id)), style: { background: "none", border: "none", color: "#94a3b8", cursor: "pointer", fontSize: 14 } }, "×") : h("span", { style: { fontSize: 9.5, color: "#94a3b8", textTransform: "uppercase", letterSpacing: ".05em" } }, "AP")))
          : h("div", { style: { fontSize: 12, color: "#6475a0", padding: "6px 4px" } }, "Nothing scheduled. Add a reminder below; upcoming AP bills appear automatically once synced."),
        h("div", { style: { display: "flex", gap: 8, marginTop: 10 } },
          h("input", { type: "date", value: newEvent.date, onChange: (e) => setNewEvent(Object.assign({}, newEvent, { date: e.target.value })), style: { padding: "7px 10px", border: "1px solid rgba(13,32,64,.15)", borderRadius: 7, fontSize: 12.5 } }),
          h("input", { value: newEvent.text, onChange: (e) => setNewEvent(Object.assign({}, newEvent, { text: e.target.value })), onKeyDown: (e) => { if (e.key === "Enter") addEvent(); }, placeholder: "Reminder…", style: { flex: 1, padding: "7px 10px", border: "1px solid rgba(13,32,64,.15)", borderRadius: 7, fontSize: 12.5 } }),
          h("button", { onClick: addEvent, style: { background: "#1C4ED8", border: "none", color: "#fff", borderRadius: 7, padding: "7px 14px", fontSize: 12, fontWeight: 700, cursor: "pointer" } }, "+ Add"))));

    // ── Section 1: executive summary ────────────────────────────────────────────
    const localSummary = "Revenue for " + windows.cur.label.toLowerCase() + " is " + money(cur.rev)
      + (cur.revP ? " (" + (cur.rev >= cur.revP ? "up" : "down") + " " + Math.abs(cur.revP ? (cur.rev - cur.revP) / Math.abs(cur.revP) * 100 : 0).toFixed(0) + "% vs " + windows.prior.label + ")" : "")
      + " at a " + (cur.gm == null ? "—" : cur.gm.toFixed(1) + "%") + " gross margin, with EBITDA of " + money(cur.ebitda) + "."
      + (cashNow != null ? " Cash on hand is " + money(cashNow) + "." : "")
      + (excItems.length ? " " + excItems.length + " open exception" + (excItems.length > 1 ? "s need" : " needs") + " review." : "");
    const summaryText = ai.summary || localSummary;
    const execSummary = h("div", { style: { background: "linear-gradient(135deg, rgba(13,32,64,.04) 0%, rgba(0,159,160,.05) 100%)", border: "1px solid rgba(13,32,64,.12)", borderLeft: "4px solid #009fa0", borderRadius: 10, padding: "18px 22px" } },
      h("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 8 } },
        h("span", { style: { fontSize: 11, fontWeight: 800, color: "#009fa0", letterSpacing: ".08em", textTransform: "uppercase" } }, "📋 Executive Summary — " + windows.cur.label),
        h("button", { onClick: () => setNonce((n) => n + 1), style: { background: "transparent", border: "1px solid rgba(0,159,160,.4)", color: "#009fa0", borderRadius: 6, padding: "4px 10px", fontSize: 11, fontWeight: 700, cursor: "pointer" } }, ai.status === "loading" ? "Regenerating…" : "Regenerate")),
      h("p", { style: { fontSize: 13.5, color: "#1a2540", lineHeight: 1.65, marginTop: 10 } }, summaryText),
      h("div", { style: { fontSize: 10.5, color: "#94a3b8", marginTop: 8 } },
        (ai.summary ? "Generated via cfo-synthesis" : "Computed from your real metrics") + (ai.ts ? " · last generated " + new Date(ai.ts).toLocaleString() : "") + " · Not financial advice"));

    // ── Header controls ─────────────────────────────────────────────────────────
    const TABS = [["week", "This Week"], ["month", "This Month"], ["last_month", "Last Month"], ["custom", "Custom"]];
    const controls = h("div", { style: { display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" } },
      h("button", { onClick: () => setNonce((n) => n + 1), style: { background: "#009fa0", border: "none", borderRadius: 7, padding: "7px 14px", color: "#fff", fontSize: 12, fontWeight: 700, cursor: "pointer" } }, "✨ Generate Briefing"),
      h("button", { onClick: () => window.print(), style: { background: "rgba(255,255,255,.14)", border: "1px solid rgba(255,255,255,.24)", borderRadius: 7, padding: "7px 12px", color: "#eef2ff", fontSize: 11.5, fontWeight: 700, cursor: "pointer" } }, "🖨 Print Briefing"));

    const tabBar = h("div", { style: { display: "flex", gap: 4, borderBottom: "1px solid rgba(13,32,64,.1)", marginBottom: 16, flexWrap: "wrap" } },
      TABS.map(([k, label]) => h("button", { key: k, onClick: () => setTab(k),
        style: { background: "transparent", border: "none", borderBottom: "2px solid " + (tab === k ? "#009fa0" : "transparent"), padding: "9px 15px", fontSize: 13, fontWeight: tab === k ? 700 : 500, cursor: "pointer", color: tab === k ? "#0d2040" : "#6475a0" } }, label)));
    const customInputs = tab === "custom" ? h("div", { style: { display: "flex", gap: 8, marginBottom: 14, alignItems: "center" } },
      h("span", { style: { fontSize: 11.5, color: "#6475a0" } }, "From"),
      h("input", { type: "date", value: custom.start, onChange: (e) => setCustom(Object.assign({}, custom, { start: e.target.value })), style: { padding: "6px 9px", border: "1px solid rgba(13,32,64,.15)", borderRadius: 7, fontSize: 12 } }),
      h("span", { style: { fontSize: 11.5, color: "#6475a0" } }, "to"),
      h("input", { type: "date", value: custom.end, onChange: (e) => setCustom(Object.assign({}, custom, { end: e.target.value })), style: { padding: "6px 9px", border: "1px solid rgba(13,32,64,.15)", borderRadius: 7, fontSize: 12 } })) : null;

    return h(K.Shell, { hero: { eyebrow: "INTELLIGENCE", title: "CFO Briefing", subtitle: "Your digest for " + windows.cur.label + " · as of " + fmtD(anchor), controls } },
      tabBar,
      customInputs,
      execSummary,
      h("div", { style: { height: 18 } }),
      whatChanged,
      exceptionsCard,
      snapshot,
      actionCard,
      comingCard);
  }

  window.CFOBriefingPage = Page;
})();
