// MarginPage (Platform rebuild) — window.MarginPage
// Profitability analysis: gross margin %, cost structure, GM bridge, COGS mix,
// and strongest/weakest margin months. Period selector (G1) + comparison (G2)
// drive every figure. All values derive from live plHistory + GL COGS accounts.

(function () {
  const h = React.createElement;
  const COGS_SECS = ["cogs"];

  function Page(props) {
    const K = window.PerduraPageKit;
    if (!K) return h("div", { className: "pc-page" }, "Loading…");
    const { data, companyProfile } = props;
    const plH = (data && (data.plHistory || data.pl)) || { labels: [], revenue: [], cogs: [], gp: [] };
    const txns = (data && data.txns) || [];
    const M = (v) => K.moneyStr(v, { compact: true });
    const anchor = K.anchorFromPlH(plH);
    const ps = K.usePeriodState("margin", "ytd");
    const range = K.resolvePeriod(ps.mode, anchor, ps.custom);
    const cmpRange = K.comparePeriod(range, ps.cmp);
    const span = K.plIdxRange(plH, range);
    const cspan = cmpRange ? K.plIdxRange(plH, cmpRange) : null;

    const rev = K.sumIdx(plH.revenue, span);
    const cogs = K.sumIdx(plH.cogs, span);
    const gp = plH.gp && plH.gp.length ? K.sumIdx(plH.gp, span) : (rev - cogs);
    const gmPct = rev ? gp / rev * 100 : null;
    const cogsPct = rev ? cogs / rev * 100 : null;
    const pRev = cspan ? K.sumIdx(plH.revenue, cspan) : 0;
    const pCogs = cspan ? K.sumIdx(plH.cogs, cspan) : 0;
    const pGp = cspan ? (plH.gp && plH.gp.length ? K.sumIdx(plH.gp, cspan) : pRev - pCogs) : 0;
    const pGmPct = pRev ? pGp / pRev * 100 : null;
    const gmDelta = (gmPct != null && pGmPct != null) ? gmPct - pGmPct : null;

    // Monthly GM% series (current + prior-year dashed) for the full history.
    const revArr = (plH.revenue || []).map(Number), cogsArr = (plH.cogs || []).map(Number), gpArr = (plH.gp || []).map(Number);
    const N = revArr.length;
    const gmSeries = revArr.map((r, i) => { const g = gpArr.length ? gpArr[i] : (r - (cogsArr[i] || 0)); return r ? g / r * 100 : null; });
    const m12 = (plH.labels || []).slice(Math.max(0, N - 12));
    const cur12 = gmSeries.slice(Math.max(0, N - 12));
    const prior12 = N >= 24 ? gmSeries.slice(N - 24, N - 12) : null;

    // COGS cost structure by category over the selected window.
    const cogsCats = K.catBreakdownWindow(txns, companyProfile, COGS_SECS, range, cmpRange);
    const cogsTotal = cogsCats.reduce((s, r) => s + r.cur, 0) || cogs;

    // Strongest / weakest margin months (trailing 12, real & derivable).
    const monthMargins = cur12.map((v, i) => ({ label: m12[i], gm: v })).filter((x) => x.gm != null);
    const byMargin = monthMargins.slice().sort((a, b) => b.gm - a.gm);
    const strongest = byMargin.slice(0, Math.min(5, byMargin.length));
    const weakest = byMargin.slice(Math.max(0, byMargin.length - 5)).reverse();

    // GM bridge (2-factor: volume at prior margin + rate/mix) — only with a comparison window.
    const volEff = (pGmPct != null) ? (rev - pRev) * (pGmPct / 100) : 0;
    const rateEff = gp - pGp - volEff;
    const bridgeItems = cspan ? [
      { label: "Prior gross profit", value: pGp, type: "start" },
      { label: "Volume effect", value: volEff, type: volEff >= 0 ? "positive" : "negative" },
      { label: "Rate / mix effect", value: rateEff, type: rateEff >= 0 ? "positive" : "negative" },
      { label: "Current gross profit", value: gp, type: "end" },
    ] : null;

    const gmColor = gmPct == null ? "navy" : gmPct >= 40 ? "green" : gmPct >= 25 ? "teal" : "amber";
    const kpis = [
      { label: "Gross Margin %", value: gmPct == null ? "—" : gmPct.toFixed(1) + "%", valueColor: "green", delta: gmDelta == null ? null : (Math.abs(gmDelta)).toFixed(1) + " pts", deltaDir: gmDelta == null ? "flat" : gmDelta >= 0 ? "up" : "dn", sub: range.label },
      { label: "Gross Profit", value: M(gp), valueColor: "green", sub: pGp ? (gp >= pGp ? "▲ " : "▼ ") + M(Math.abs(gp - pGp)) + " vs " + (cmpRange ? cmpRange.label.toLowerCase() : "prior") : "selected period" },
      { label: "COGS", value: M(cogs), valueColor: "red", sub: cogsPct == null ? "cost of goods" : cogsPct.toFixed(0) + "% of sales" },
      { label: "Contribution Margin %", value: "—", valueColor: "teal", sub: "needs variable-cost tagging" },
      { label: "COGS % of Sales", value: cogsPct == null ? "—" : cogsPct.toFixed(1) + "%", valueColor: "red", sub: "lower is better" },
    ];

    const swatch = (color, label, dashed) => h("span", { style: { display: "inline-flex", alignItems: "center", gap: 5, fontSize: 10, color: "#475569", fontWeight: 600 } },
      h("span", { style: { width: 14, height: dashed ? 0 : 8, borderRadius: 2, background: dashed ? "transparent" : color, borderTop: dashed ? "2px dashed " + color : "none", display: "inline-block" } }), label);

    const gmChartSeries = [
      { type: "line", color: "#059669", data: cur12 },
      prior12 ? { type: "dashed-line", color: "#94a3b8", data: prior12 } : null,
    ].filter(Boolean);

    const trendTakeaway = "Gross margin is <b>" + (gmPct == null ? "—" : gmPct.toFixed(1) + "%") + "</b> for " + range.label.toLowerCase() +
      (gmDelta == null ? "." : ", " + (gmDelta >= 0 ? "up" : "down") + " <b>" + Math.abs(gmDelta).toFixed(1) + " pts</b> vs " + (cmpRange ? cmpRange.label.toLowerCase() : "prior") + ".") +
      (strongest.length ? " Strongest recent month: <b>" + strongest[0].label + "</b> at " + strongest[0].gm.toFixed(1) + "%." : "");

    const marginTable = (rows, title, sub, flagNeg) => h(K.Card, { title: title, sub: sub, padding: 0 },
      rows.length ? h("table", { className: "pa-table" },
        h("thead", null, h("tr", null, h("th", null, "Month"), h("th", { className: "num" }, "Gross Margin %"))),
        h("tbody", null, rows.map((r, i) => h("tr", { key: i, title: "View expense detail",
          onClick: () => window.__perduraSetPage && window.__perduraSetPage("opex_intelligence"),
          style: Object.assign({ cursor: "pointer" }, flagNeg && r.gm < 0 ? { background: "rgba(217,79,71,.06)" } : null) },
          h("td", { style: { fontWeight: 600 } }, r.label, flagNeg && r.gm < 0 ? h("span", { style: { color: "#d94f47", marginLeft: 6 } }, "⚠ negative") : null),
          h("td", { className: "num", style: { fontWeight: 700, color: r.gm >= 40 ? "#059669" : r.gm >= 25 ? "#0891B2" : r.gm < 0 ? "#d94f47" : "#d97706" } }, r.gm == null ? "—" : r.gm.toFixed(1) + "%")))))
        : h("div", { className: "pa-card-body", style: { color: "#6475a0", fontSize: 13 } }, "Not enough monthly history yet."));

    return h(K.Shell, { hero: {
      eyebrow: "PROFITABILITY ANALYSIS", title: "Gross Margin & Cost Structure",
      subtitle: range.label + (cmpRange ? " · vs " + cmpRange.label.toLowerCase() : "") + " · from GL revenue & COGS accounts",
      controls: h(K.PeriodControls, ps),
    } },

      // Row 1 — KPI tiles
      h("div", { className: "pa-kpi-strip pa-kpi-strip-5" }, kpis.map((k, i) => h(K.Kpi, Object.assign({ key: i, animDelay: i * 0.05, onClick: () => window.__perduraSetPage && window.__perduraSetPage("income_statement") }, k)))),

      h("div", { style: { fontSize: 10, color: "#6475a0", padding: "2px 2px 10px", display: "flex", alignItems: "center", gap: 6 } },
        h("span", null, "💡"), "Click account rows to drill into transactions · Click metrics to navigate to detail pages"),

      // Row 2 — GM% over time + cost structure
      h("div", { className: "pa-grid-2" },
        h(K.Card, { title: "GROSS MARGIN % — TREND", sub: "12 months · prior year dashed", right: h("div", { style: { display: "flex", gap: 12 } }, swatch("#059669", "Current"), prior12 ? swatch("#94a3b8", "Prior year", true) : null) },
          h(K.MultiSeriesBarChart, { months: m12, series: gmChartSeries, height: 180 }),
          h(K.KeyTakeaway, { text: trendTakeaway })),
        h(K.Card, { title: "Cost structure — COGS by category", sub: "Share of COGS · " + range.label },
          cogsCats.length ? h(K.RankedList, { items: cogsCats.slice(0, 8).map((r) => ({ label: r.name, pct: cogsTotal ? r.cur / cogsTotal * 100 : 0 })), onItemClick: (item) => window.openAccountDetail && window.openAccountDetail({ name: item.label, category: "cogs", page: "margin" }) })
            : h("div", { style: { color: K.MUTE, fontSize: 12, padding: 12 } }, "No classified COGS in this period. Product-level margin requires a COGS-by-product mapping."))),

      // Row 3 — GM bridge + COGS mix donut
      h("div", { className: "pa-grid-2" },
        h(K.Card, { title: "Gross profit bridge", sub: cmpRange ? "Prior → volume → rate/mix → current" : "Select a comparison to view the bridge" },
          bridgeItems ? h(K.BridgeChart, { items: bridgeItems })
            : h("div", { style: { color: K.MUTE, fontSize: 12, padding: 12 } }, "Choose a comparison (Prior Period / Prior Year) to decompose the gross-profit change.")),
        h(K.Card, { title: "COGS breakdown", sub: "By category · " + range.label },
          cogsCats.length ? h(K.Donut, { items: cogsCats.slice(0, 6).map((r, i) => ({ label: r.name, value: r.cur, color: K.RANK_COLORS[i % K.RANK_COLORS.length] })) })
            : h("div", { style: { color: K.MUTE, fontSize: 12, padding: 12 } }, "No classified COGS yet."))),

      // Row 4 — strongest / weakest margin months
      h("div", { className: "pa-grid-2" },
        marginTable(strongest, "Strongest margin months", "Highest GM% · trailing 12", false),
        marginTable(weakest, "Weakest margin months", "Lowest GM% · trailing 12 · flags negative", true)),

      // Row 5 — CFO margin intelligence
      h(K.Commentary, { title: "CFO margin intelligence", items: [
        { icon: "▣", text: "Gross margin is <b>" + (gmPct == null ? "—" : gmPct.toFixed(1) + "%") + "</b> on " + M(rev) + " revenue (" + range.label.toLowerCase() + ")" + (gmDelta == null ? "." : ", " + (gmDelta >= 0 ? "expanding" : "compressing") + " <b>" + Math.abs(gmDelta).toFixed(1) + " pts</b> vs " + (cmpRange ? cmpRange.label.toLowerCase() : "prior") + ".") },
        cogsCats.length ? { icon: "◆", text: "Largest cost line is <b>" + cogsCats[0].name + "</b> at " + (cogsTotal ? (cogsCats[0].cur / cogsTotal * 100).toFixed(0) : "0") + "% of COGS." } : null,
        bridgeItems ? { icon: rateEff >= 0 ? "▲" : "▼", text: "Margin change is driven " + (Math.abs(rateEff) > Math.abs(volEff) ? "mostly by <b>rate/mix</b>" : "mostly by <b>volume</b>") + " (rate/mix " + (rateEff >= 0 ? "+" : "−") + M(Math.abs(rateEff)) + ", volume " + (volEff >= 0 ? "+" : "−") + M(Math.abs(volEff)) + ")." } : null,
        { icon: "➜", text: "<b>Recommended action:</b> " + (gmPct != null && gmPct < 25 ? "Margins are thin — review pricing and the largest COGS categories for cost-out opportunities." : gmDelta != null && gmDelta < -2 ? "Margin is compressing — investigate cost inflation and discounting before it reaches the bottom line." : "Protect the current margin profile as volume scales; watch the largest cost lines for creep.") },
      ].filter(Boolean) }));
  }
  window.MarginPage = Page;
})();
