// DummiesGuidePage (Stage 11) — window.DummiesGuidePage
// "What Your Numbers Mean" — plain-English, friendly cards explaining each key
// metric with the company's actual current values, an industry benchmark bar,
// and dynamic "what's happening / watch for / do" guidance. Definitions are
// built in (so the page always works) and enriched by kpi_library where keys
// match. All numbers are live from data; nothing is fabricated.

(function () {
  const h = React.createElement;
  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)) || {};
    const T = K.ttm(plH);
    const cash = (data && data.cash) || null;
    const aging = (data && data.aging) || null;
    const np = companyProfile && (companyProfile.is_nonprofit || /nonprofit|faith/i.test(companyProfile.business_type || companyProfile.archetype || ""));

    const rev = T ? T.cur.revenue : 0, revP = (T && T.prior) ? T.prior.revenue : null;
    const yoy = revP ? (rev - revP) / Math.abs(revP) * 100 : null;
    const gm = (T && T.cur.revenue) ? T.cur.gp / T.cur.revenue * 100 : null;
    const gmP = (T && T.prior && T.prior.revenue) ? T.prior.gp / T.prior.revenue * 100 : null;
    const em = (T && T.cur.revenue) ? T.cur.ebitda / T.cur.revenue * 100 : null;
    const opr = (T && T.cur.revenue) ? T.cur.opex / T.cur.revenue * 100 : null;
    const startCash = cash && Number.isFinite(cash.startCash) ? cash.startCash : null;
    const runwayMo = cash && Number.isFinite(cash.runwayDays) ? cash.runwayDays / 30 : null;
    const arTotal = aging && aging.ar && aging.ar.buckets ? aging.ar.buckets.reduce((s, b) => s + (b.value || 0), 0) : null;
    const apTotal = aging && aging.ap && aging.ap.buckets ? aging.ap.buckets.reduce((s, b) => s + (b.value || 0), 0) : null;
    const dso = (arTotal != null && rev) ? arTotal / rev * 365 : null;
    const dpo = (apTotal != null && (T && T.cur.cogs)) ? apTotal / T.cur.cogs * 365 : null;

    // status helper: (value, good-if) → 🟢🟡🔴
    const st = (ok, near) => ok ? "green" : near ? "amber" : "red";
    const COLORS = { green: "#059669", amber: "#D97706", red: "#DC2626", none: "#64748b" };

    const cards = [];
    const add = (c) => { if (c.value != null) cards.push(c); };

    add({ emoji: "💰", name: np ? "Total Income" : "Revenue", valueNum: rev, value: rev != null ? K.moneyStr(rev, { compact: true }) : null,
      status: yoy == null ? "none" : st(yoy >= 0, yoy >= -5),
      whatItIs: "The total money coming into your business over the last 12 months from sales" + (np ? ", donations, and grants." : " of your products or services."),
      bench: null,
      why: "Revenue is the top of the funnel — every other number flows from it. Growing revenue gives you room to invest and absorb cost increases.",
      happening: yoy == null ? "You have " + K.moneyStr(rev, { compact: true }) + " of revenue in the last year." : "Your revenue is " + K.moneyStr(rev, { compact: true } ) + ", " + (yoy >= 0 ? "up" : "down") + " " + Math.abs(yoy).toFixed(1) + "% from the year before.",
      watch: yoy != null && yoy < 0 ? "Revenue is shrinking — find out which products or customers dropped off." : null,
      todo: yoy != null && yoy < 0 ? ["Review your top customers for any that reduced spend", "Double down on the streams still growing"] : ["Keep investing in what's working", "Track which streams grow fastest month to month"] });

    add({ emoji: "📊", name: "Gross Margin", valueNum: gm, value: gm != null ? gm.toFixed(1) + "%" : null,
      status: gm == null ? "none" : st(gm >= 45, gm >= 30),
      whatItIs: "For every $1 of sales, this is how much you keep after paying the direct cost of making your product or delivering your service.",
      bench: { p25: 25, p50: 45, p75: 60, value: gm }, benchUnit: "%",
      why: "Higher margin means more money to cover overhead and keep as profit. If it drops, your costs are rising faster than your prices.",
      happening: gm != null ? "You keep about $" + (gm / 100).toFixed(2) + " of every sales dollar" + (gmP != null ? ", " + (gm - gmP >= 0 ? "up" : "down") + " " + Math.abs(gm - gmP).toFixed(1) + "pp from last year." : ".") : null,
      watch: (gmP != null && gm - gmP < -1) ? "Your margin dipped " + Math.abs(gm - gmP).toFixed(1) + "pp — check if supplier costs rose or you discounted more." : null,
      todo: ["Review your top 3 cost items for negotiation room", "Consider a small price increase on your lowest-margin items"] });

    add({ emoji: "⚙️", name: np ? "Operating Surplus" : "EBITDA", valueNum: em, value: (T && T.cur.ebitda != null) ? K.moneyStr(T.cur.ebitda, { compact: true }) + (em != null ? " · " + em.toFixed(1) + "%" : "") : null,
      status: em == null ? "none" : st(em >= 15, em >= 5),
      whatItIs: "What's left from " + (np ? "income" : "revenue") + " after running costs — before interest, tax, and depreciation. A clean read on whether operations make money.",
      bench: { p25: 5, p50: 15, p75: 25, value: em }, benchUnit: "%",
      why: "This is your core profitability. Positive and growing means the business funds itself; negative means you're burning cash to operate.",
      happening: em != null ? "Your operating profit margin is " + em.toFixed(1) + "% of " + (np ? "income" : "revenue") + "." : null,
      watch: em != null && em < 5 ? "Thin operating margin — small cost increases could push you into a loss." : null,
      todo: ["Protect margin: keep cost growth below revenue growth", "Trim the largest controllable overhead line"] });

    add({ emoji: "🏦", name: "Cash on Hand", valueNum: startCash, value: startCash != null ? K.moneyStr(startCash, { compact: true }) : null,
      status: startCash == null ? "none" : st(startCash > 0, startCash >= 0),
      whatItIs: "The actual money in your bank accounts right now. Not profit — real, spendable cash.",
      bench: null,
      why: "Profit is an opinion; cash is a fact. You can be profitable and still run out of cash if money is tied up in receivables or inventory.",
      happening: startCash != null ? "You have about " + K.moneyStr(startCash, { compact: true }) + " of cash available." : null,
      watch: null,
      todo: ["Keep a buffer of 2-3 months of expenses", "Watch the gap between profit and cash — it's working capital"] });

    add({ emoji: "⏳", name: "Days of Cash Runway", valueNum: runwayMo, value: runwayMo != null ? (runwayMo >= 99 ? "∞" : runwayMo.toFixed(1) + " mo") : null,
      status: runwayMo == null ? "none" : st(runwayMo >= 6, runwayMo >= 3),
      whatItIs: "If income stopped today, how long your current cash would keep the lights on at today's spending rate.",
      bench: null,
      why: "This is the survival metric. Under 3 months is a red flag; 6+ months gives you room to handle surprises and make decisions calmly.",
      happening: runwayMo != null ? (runwayMo >= 99 ? "You're building cash — runway is effectively unlimited at the current rate." : "At today's burn, your cash lasts about " + runwayMo.toFixed(1) + " months.") : null,
      watch: runwayMo != null && runwayMo < 3 ? "Runway is short — protect inflows and defer non-urgent spending now." : null,
      todo: runwayMo != null && runwayMo < 6 ? ["Speed up collections on overdue invoices", "Pause discretionary spend until runway is 6+ months"] : ["Consider putting idle cash to work", "Keep monitoring monthly"] });

    add({ emoji: "🧾", name: "Operating Cost Ratio", valueNum: opr, value: opr != null ? opr.toFixed(1) + "%" : null,
      status: opr == null ? "none" : st(opr <= 70, opr <= 85),
      whatItIs: "How much of every revenue dollar goes to running costs (rent, salaries, software, etc.) — excluding the direct cost of your product.",
      bench: { p25: 60, p50: 75, p75: 90, value: opr, lowerBetter: true }, benchUnit: "%",
      why: "Lower is leaner. If this creeps up while revenue is flat, overhead is growing faster than the business can support.",
      happening: opr != null ? Math.round(opr) + " cents of every dollar goes to overhead." : null,
      watch: opr != null && opr > 85 ? "Overhead is eating most of your revenue — review fixed costs." : null,
      todo: ["Audit recurring software and subscriptions", "Renegotiate your largest fixed contracts at renewal"] });

    add({ emoji: "📈", name: "Revenue Growth Rate", valueNum: yoy, value: yoy != null ? (yoy >= 0 ? "+" : "") + yoy.toFixed(1) + "%" : null,
      status: yoy == null ? "none" : st(yoy >= 5, yoy >= 0),
      whatItIs: "How fast your " + (np ? "income" : "revenue") + " is growing compared to a year ago.",
      bench: null,
      why: "Steady growth compounds. Flat or negative growth means you need new customers, more from existing ones, or higher prices.",
      happening: yoy != null ? "Your revenue " + (yoy >= 0 ? "grew" : "fell") + " " + Math.abs(yoy).toFixed(1) + "% year over year." : null,
      watch: yoy != null && yoy < 0 ? "Growth turned negative — diagnose the cause before it compounds." : null,
      todo: ["Set a realistic growth target and track monthly", "Focus on the 20% of customers driving 80% of revenue"] });

    if (dso != null) add({ emoji: "📨", name: "Collection Days (DSO)", valueNum: dso, value: Math.round(dso) + " days",
      status: st(dso <= 45, dso <= 60),
      whatItIs: "On average, how many days it takes customers to pay you after you invoice them.",
      bench: { p25: 30, p50: 45, p75: 60, value: dso, lowerBetter: true }, benchUnit: "d",
      why: "Every day customers don't pay is a day your cash is tied up. Faster collection = more cash to run and grow.",
      happening: "Customers take about " + Math.round(dso) + " days to pay on average.",
      watch: dso > 60 ? "Collections are slow — over 60 days ties up significant cash." : null,
      todo: ["Send reminders before invoices come due", "Offer a small early-payment discount"] });

    if (dpo != null) add({ emoji: "📤", name: "Payment Days (DPO)", valueNum: dpo, value: Math.round(dpo) + " days",
      status: st(dpo >= 30, dpo >= 20),
      whatItIs: "On average, how many days you take to pay your suppliers after they invoice you.",
      bench: { p25: 25, p50: 40, p75: 55, value: dpo }, benchUnit: "d",
      why: "Paying a bit slower (without late fees) keeps cash in your business longer — but don't damage supplier relationships.",
      happening: "You pay suppliers in about " + Math.round(dpo) + " days on average.",
      watch: dpo < 15 ? "You're paying very fast — you may be giving up free working capital." : null,
      todo: ["Negotiate net-30 or net-45 terms with key suppliers", "Pay on the due date, not before — unless there's a discount"] });

    const Bench = ({ b, unit }) => {
      if (!b || b.value == null) return null;
      const lo = b.p25, hi = b.p75, span = (hi - lo) || 1;
      const posPct = Math.max(0, Math.min(100, (b.value - lo) / span * 100));
      const good = b.lowerBetter ? b.value <= b.p50 : b.value >= b.p50;
      return h("div", { style: { margin: "8px 0" } },
        h("div", { style: { position: "relative", height: 8, background: "#E4E8F0", borderRadius: 4 } },
          h("div", { style: { height: "100%", width: posPct + "%", borderRadius: 4, background: good ? "linear-gradient(90deg,#059669,#10B981)" : "linear-gradient(90deg,#D97706,#F59E0B)" } }),
          h("div", { style: { position: "absolute", top: -3, left: posPct + "%", width: 2, height: 14, background: "#0F1520", borderRadius: 1 } })),
        h("div", { style: { fontSize: 11, color: "#4B5563", marginTop: 4 } }, b.value.toFixed(1) + unit + " — " + (good ? "at or better than" : "below") + " the industry median (" + b.p50 + unit + ")"));
    };

    const H3 = (t) => h("div", { style: { fontSize: 12, fontWeight: 700, color: "#3B4559", marginTop: 14, marginBottom: 3 } }, t);
    const P = (t) => h("div", { style: { fontSize: 13, color: "#4B5563", lineHeight: 1.6 } }, t);

    return h(K.Shell, { hero: { eyebrow: "PLAIN ENGLISH", title: "What Your Numbers Mean", subtitle: "A simple guide to understanding your business finances — no accounting degree required" } },
      h("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(380px, 1fr))", gap: 16 } },
        cards.map((c, i) => h("div", { key: i, style: { background: "#fff", borderRadius: 16, padding: 24, boxShadow: "0 2px 12px rgba(0,0,0,0.06)", border: "1px solid #E4E8F0", borderTop: "4px solid " + COLORS[c.status] } },
          h("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10 } },
            h("div", { style: { display: "flex", alignItems: "center", gap: 10 } },
              h("span", { style: { fontSize: 24 } }, c.emoji),
              h("h3", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: 1, color: "#6B7A99", margin: 0 } }, c.name)),
            h("div", { style: { display: "flex", alignItems: "center", gap: 8 } },
              h("span", { style: { fontSize: 28, fontWeight: 800, color: "#0F1520", letterSpacing: -1, fontFamily: "'JetBrains Mono','Geist Mono',monospace" } }, c.value),
              h("span", { style: { fontSize: 16 } }, c.status === "green" ? "🟢" : c.status === "amber" ? "🟡" : c.status === "red" ? "🔴" : "⚪"))),
          H3("What it is"), P(c.whatItIs),
          c.bench ? h(React.Fragment, null, H3("Is this good?"), h(Bench, { b: c.bench, unit: c.benchUnit })) : null,
          H3("Why it matters"), P(c.why),
          c.happening ? h(React.Fragment, null, H3("What's happening"), P(c.happening)) : null,
          c.watch ? h(React.Fragment, null, H3("What to watch for"), h("div", { style: { fontSize: 13, color: "#B45309", background: "rgba(217,119,6,0.06)", border: "1px solid rgba(217,119,6,0.2)", borderRadius: 8, padding: "8px 10px", lineHeight: 1.5, marginTop: 2 } }, "⚠ " + c.watch)) : null,
          (c.todo && c.todo.length) ? h(React.Fragment, null, H3("What to do"), h("div", { style: { display: "flex", flexDirection: "column", gap: 4, marginTop: 2 } }, c.todo.map((t, j) => h("div", { key: j, style: { fontSize: 13, color: "#1C4ED8", lineHeight: 1.5 } }, "→ " + t)))) : null))));
  }
  window.DummiesGuidePage = Page;
})();
