/* ============================================================
   RESTO SUITE — FINANCIAL FEASIBILITY MODULE
   Reads/writes: plan.financials (its own namespace only)
   Reads: plan.idea (to pre-fill seats / avg check hints)
   Reuses: InvCategory, SpaceCard, INV_SUGGEST, COST_SUGGEST
           (investment-details.jsx), PageSummary, FinancialSummary
           (financial-summary.jsx), primitives (suite-shared.jsx)
   ============================================================ */
const { useState: useStateF, useMemo: useMemoF } = React;

function computeFin(state, t) {
  const invVals = {};
  for (const k in state.investment) {
    const its = (state.invItems || {})[k] || [];
    invVals[k] = its.length ? its.reduce((a, i) => a + (i.qty || 0) * (i.price || 0), 0) : state.investment[k];
  }
  const investment = Object.values(invVals).reduce((a, b) => a + b, 0);

  let sales;
  if (state.revMode === "detailed") {
    const d = state.detailed;
    sales = d.seats * d.turns * d.avgCheck * d.openDays;
  } else sales = state.monthlySales;

  const foodPct = state.foodPct;
  const foodCost = sales * foodPct;
  const costVal = (k) => {
    const its = (state.costItems || {})[k] || [];
    return its.length ? its.reduce((a, i) => a + (i.qty || 0) * (i.price || 0), 0) : state[k];
  };
  const costs = {
    staff: costVal("staff"), rent: costVal("rent"), utilities: costVal("utilities"),
    marketing: costVal("marketing"), management: costVal("management") || 0, other: costVal("other"),
    taxes: costVal("taxes") || 0,
  };
  const fixed = costs.staff + costs.rent + costs.utilities + costs.marketing + costs.management + costs.other;
  const taxTotal = costs.taxes || 0;
  const totalCost = foodCost + fixed + taxTotal;
  const profit = sales - (foodCost + fixed); // pre-tax operating profit (EBITDA)
  const margin = sales > 0 ? profit / sales : 0;

  const cmRatio = 1 - foodPct;
  const breakEven = cmRatio > 0 ? fixed / cmRatio : Infinity;
  const openDays = state.revMode === "detailed" ? state.detailed.openDays : 26;
  const breakEvenDaily = breakEven / openDays;
  const payback = profit > 0 ? investment / profit : Infinity;

  /* ---------- taxes: now a single manual line inside Operating Cost ---------- */
  const tax = { ...((FIN_DEFAULTS && FIN_DEFAULTS.tax) || {}), ...(state.tax || {}) };
  const annualGross = sales * 12;
  const netSales = sales, outputVat = 0, inputVat = 0, netVat = 0, vatApplies = false;
  const ssoHeads = 0, sso = 0, cit = 0;
  const profitBeforeTax = profit;
  const annualPBT = profit * 12;
  const netProfit = sales - totalCost; // take-home after the taxes line
  const netMargin = sales > 0 ? netProfit / sales : 0;
  const paybackAfterTax = netProfit > 0 ? investment / netProfit : Infinity;

  const share = (v) => (sales > 0 ? v / sales : 0);
  const segs = [
    { key: "food", label: t("fin.segFood"), value: foodCost, pct: share(foodCost), color: "var(--c-food)" },
    { key: "staff", label: t("fin.segStaff"), value: costs.staff, pct: share(costs.staff), color: "var(--c-staff)" },
    { key: "rent", label: t("fin.segRent"), value: costs.rent, pct: share(costs.rent), color: "var(--c-rent)" },
    { key: "utilities", label: t("fin.segUtil"), value: costs.utilities, pct: share(costs.utilities), color: "var(--c-util)" },
    { key: "marketing", label: t("fin.segMkt"), value: costs.marketing, pct: share(costs.marketing), color: "var(--c-mkt)" },
    { key: "management", label: t("fin.segMgmt"), value: costs.management, pct: share(costs.management), color: "var(--c-mgmt)" },
    { key: "other", label: t("fin.segOther"), value: costs.other, pct: share(costs.other), color: "var(--c-other)" },
    ...(taxTotal > 0 ? [{ key: "tax", label: t("fin.segTax"), value: taxTotal, pct: share(taxTotal), color: "var(--c-tax)" }] : []),
  ];

  let verdict;
  if (sales <= 0) verdict = { key: "none", label: t("fin.verdictNone"), tone: "muted" };
  else if (netProfit <= 0) verdict = { key: "loss", label: t("fin.verdictLoss"), tone: "red" };
  else if (netMargin < 0.05) verdict = { key: "risky", label: t("fin.verdictRisky"), tone: "amber" };
  else if (netMargin < 0.12) verdict = { key: "ok", label: t("fin.verdictOk"), tone: "amber" };
  else if (netMargin < 0.20) verdict = { key: "healthy", label: t("fin.verdictHealthy"), tone: "green" };
  else verdict = { key: "strong", label: t("fin.verdictStrong"), tone: "green" };

  const staffPct = share(costs.staff), rentPct = share(costs.rent), primePct = foodPct + staffPct;
  const flags = [];
  if (sales > 0) {
    if (foodPct > 0.38) flags.push({ tone: "amber", text: t("idea.flagFoodHigh", { pct: fmtPct(foodPct) }) });
    else if (foodPct < 0.20) flags.push({ tone: "amber", text: t("idea.flagFoodLow", { pct: fmtPct(foodPct) }) });
    else flags.push({ tone: "green", text: t("idea.flagFoodHealthy", { pct: fmtPct(foodPct) }) });
    if (staffPct > 0.40) flags.push({ tone: "amber", text: t("idea.flagStaffHigh", { pct: fmtPct(staffPct) }) });
    if (primePct > 0.65) flags.push({ tone: "red", text: t("idea.flagPrimeHigh", { pct: fmtPct(primePct) }) });
    if (rentPct > 0.15) flags.push({ tone: "amber", text: t("idea.flagRentHigh", { pct: fmtPct(rentPct) }) });
    if (profit > 0 && margin >= 0.12) flags.push({ tone: "green", text: t("idea.flagMarginGood", { pct: fmtPct(margin) }) });
    if (profit <= 0) flags.push({ tone: "red", text: t("idea.flagLoss") });
    if (isFinite(payback) && payback > 48) flags.push({ tone: "amber", text: t("idea.flagPaybackSlow", { months: fmtMonths(payback) }) });
    if (taxTotal === 0 && profit > 0) flags.push({ tone: "amber", text: t("idea.flagNoTax") });
  }

  const capex = invVals.renovation + invVals.equipment + invVals.furniture + invVals.licenses + (invVals.management || 0);
  const shopSqm = (state.space || {}).shopSqm || 0;
  const kitchenSqm = (state.space || {}).kitchenSqm || 0;
  const capexPerSqm = shopSqm > 0 ? capex / shopSqm : NaN;
  const kitchenPerSqm = kitchenSqm > 0 ? invVals.equipment / kitchenSqm : NaN;
  const reserveMonths = fixed > 0 ? invVals.reserve / fixed : NaN;
  const detailedMode = state.revMode === "detailed";
  const custDay = detailedMode ? state.detailed.seats * state.detailed.turns : NaN;
  const avgCheck = detailedMode ? state.detailed.avgCheck : NaN;

  return {
    investment, invVals, costs, sales, foodCost, fixed, totalCost, profit, margin,
    breakEven, breakEvenDaily, payback, segs, verdict, flags,
    staffPct, rentPct, primePct, foodPct,
    salesDaily: sales / openDays,
    capex, capexPerSqm, kitchenPerSqm, reserveMonths, detailedMode, custDay, avgCheck,
    tax, annualGross, vatApplies, netSales, outputVat, inputVat, netVat,
    ssoHeads, sso, profitBeforeTax, annualPBT, cit, taxTotal, netProfit, netMargin, paybackAfterTax,
  };
}

/* ---------- steps ---------- */
const INV_FIELDS = [
  ["renovation", "invRenoLabel", "invRenoHint"],
  ["equipment", "invEquipLabel", "invEquipHint"],
  ["furniture", "invFurnLabel", "invFurnHint"],
  ["deposit", "invDepositLabel", "invDepositHint"],
  ["licenses", "invLicLabel", "invLicHint"],
  ["management", "invMgmtLabel", "invMgmtHint"],
  ["inventory", "invInvLabel", "invInvHint"],
  ["reserve", "invReserveLabel", "invReserveHint"],
];
const COST_FIELDS = [
  ["staff", "costStaffLabel", "costStaffHint"],
  ["rent", "costRentLabel", "costRentHint"],
  ["utilities", "costUtilLabel", "costUtilHint"],
  ["marketing", "costMktLabel", "costMktHint"],
  ["management", "costMgmtLabel", "costMgmtHint"],
  ["other", "costOtherLabel", "costOtherHint"],
  ["taxes", "costTaxLabel", "costTaxHint"],
];

function FinStepInvestment({ state, set, live, summary }) {
  const { t, lang } = useLang();
  return (
    <StepShell k="inv" kicker={t("fin.invKicker")} title={t("fin.invTitle")} lead={t("fin.invLead")}>
      <div style={card}>
        {INV_FIELDS.map(([k, labelKey, hintKey]) => (
          <InvCategory key={k} label={t("fin." + labelKey)}
            hint={t("fin." + hintKey)}
            value={state.investment[k] || 0}
            items={(state.invItems || {})[k] || []}
            onValue={(v) => set({ investment: { ...state.investment, [k]: v } })}
            onItems={(items) => set({ invItems: { ...state.invItems, [k]: items } })}
            suggestions={(INV_SUGGEST[k] && INV_SUGGEST[k][lang]) || []} />
        ))}
        <TotalRow label={t("fin.totalToOpen")} value={fmtBaht(live.investment)} />
      </div>
      <SpaceCard space={state.space || { shopSqm: 0, kitchenSqm: 0 }} onChange={(p) => set({ space: { ...state.space, ...p } })} />
      <Tip>{t("fin.reserveTip")}</Tip>
      {summary && (
        <PageSummary note={t("fin.stepSummaryNote")} items={[
          { label: t("fin.totalCapex"), value: money(live.capex), sub: t("fin.buildSystems") },
          { label: t("fin.capexPerSqm"), value: isFinite(live.capexPerSqm) ? fmtBaht(live.capexPerSqm) : "—", sub: isFinite(live.capexPerSqm) ? t("fin.shopAreaSub") : t("fin.addShopSqm") },
          { label: t("fin.kitchenPerSqm"), value: isFinite(live.kitchenPerSqm) ? fmtBaht(live.kitchenPerSqm) : "—", sub: isFinite(live.kitchenPerSqm) ? t("fin.equipKitchen") : t("fin.addKitchenSqm") },
          { label: t("fin.reserveCovers"), value: isFinite(live.reserveMonths) && live.reserveMonths > 0 ? live.reserveMonths.toFixed(1) + " mo" : "—", sub: t("fin.ofFixedCosts") },
          { label: t("fin.capitalRequired"), value: money(live.investment), sub: t("fin.everythingUpfront") },
        ]} />
      )}
    </StepShell>
  );
}

function FinStepSales({ state, set, live, summary, idea }) {
  const { t } = useLang();
  const d = state.detailed;
  const ideaSeats = idea && idea.format && idea.format.seats > 0 ? idea.format.seats : null;
  return (
    <StepShell k="sales" kicker={t("fin.salesKicker")} title={t("fin.salesTitle")} lead={t("fin.salesLead")}>
      <Segmented value={state.revMode} onChange={(v) => set({ revMode: v })}
        options={[{ v: "simple", l: t("fin.haveTarget") }, { v: "detailed", l: t("fin.helpEstimate") }]} />
      {state.revMode === "simple" ? (
        <div style={{ ...card, marginTop: 18 }}>
          <div style={{ fontWeight: 600, fontSize: 15.5 }}>{t("fin.expectedMonthlySales")}</div>
          <div style={{ color: "var(--muted)", fontSize: 13.5, marginTop: 3, marginBottom: 16 }}>{t("fin.monthlySalesDesc")}</div>
          <Amount large value={state.monthlySales} onChange={(v) => set({ monthlySales: v })} />
          <div style={{ marginTop: 16, color: "var(--muted)", fontSize: 14.5 }}>{t("fin.aboutADay", { x: fmtBaht(live.salesDaily) })}</div>
        </div>
      ) : (
        <div style={{ ...card, marginTop: 18 }}>
          {ideaSeats && ideaSeats !== d.seats && (
            <div style={{ marginBottom: 14, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, padding: "10px 14px", background: "var(--accent-tint)", borderRadius: 11 }}>
              <span style={{ fontSize: 13.5, color: "var(--ink)" }}>{t("fin.briefSaysSeats", { n: ideaSeats })}</span>
              <button onClick={() => set({ detailed: { ...d, seats: ideaSeats } })} style={{ ...btnGhost, padding: "7px 14px", fontSize: 12.5, borderRadius: 9 }}>{t("fin.useIt")}</button>
            </div>
          )}
          <FieldRow label={t("fin.seats")} hint={t("fin.seatsHint2")}><Stepper value={d.seats} onChange={(v) => set({ detailed: { ...d, seats: v } })} step={2} /></FieldRow>
          <FieldRow label={t("fin.tableTurns")} hint={t("fin.tableTurnsHint")}><Stepper value={d.turns} onChange={(v) => set({ detailed: { ...d, turns: v } })} step={0.1} suffix="×" /></FieldRow>
          <FieldRow label={t("fin.avgSpend")} hint={t("fin.avgSpendHint")}><Amount value={d.avgCheck} onChange={(v) => set({ detailed: { ...d, avgCheck: v } })} /></FieldRow>
          <FieldRow label={t("fin.openDays")} last><Stepper value={d.openDays} onChange={(v) => set({ detailed: { ...d, openDays: v } })} max={31} suffix="days" /></FieldRow>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", paddingTop: 20 }}>
            <div><div style={{ fontWeight: 600, fontSize: 16 }}>{t("fin.estMonthlySales")}</div><div style={{ color: "var(--muted)", fontSize: 13.5 }}>{t("fin.perDayApprox", { x: fmtBaht(live.salesDaily) })}</div></div>
            <span className="serif-fig" style={{ fontSize: 30, color: "var(--navy)" }}>{fmtBaht(live.sales)}</span>
          </div>
        </div>
      )}
      {summary && (
        <PageSummary note={t("fin.stepSummaryNote")} items={[
          { label: t("fin.salesPerMonth"), value: money(live.sales) },
          { label: t("fin.salesPerDay"), value: money(live.salesDaily) },
          { label: t("fin.avgCustValue"), value: live.detailedMode ? fmtBaht(live.avgCheck) : "—", sub: live.detailedMode ? t("fin.spendPerHead") : t("fin.useHelpEstimate") },
          { label: t("fin.custPerDay"), value: live.detailedMode ? fmt(live.custDay) : "—", sub: live.detailedMode ? t("fin.seatsTimesTurns") : t("fin.useHelpEstimate") },
        ]} />
      )}
    </StepShell>
  );
}

function FinStepCosts({ state, set, live, summary }) {
  const { t, lang } = useLang();
  const share = (v) => (live.sales > 0 && v > 0 ? t("fin.ofSalesShare", { pct: fmtPct(v / live.sales) }) : null);
  return (
    <StepShell k="costs" kicker={t("fin.costsKicker")} title={t("fin.costsTitle")} lead={t("fin.costsLead")}>
      <div style={card}>
        <div style={{ paddingBottom: 20, borderBottom: "1px solid var(--border)" }}>
          <div style={{ fontWeight: 600, fontSize: 15.5 }}>{t("fin.operatingCost")}</div>
          <div style={{ color: "var(--muted)", fontSize: 13.5, marginTop: 3, marginBottom: 16 }}>
            {t("fin.operatingCostDesc")}
          </div>
          <div style={{ fontWeight: 600, fontSize: 13.5, marginBottom: 9 }}>{t("fin.foodDrink")}<span style={{ color: "var(--muted)", fontWeight: 500 }}>{t("fin.foodDrinkSub", { sales: fmtBaht(live.sales), food: fmtBaht(live.foodCost) })}</span></div>
          <PercentSlider value={state.foodPct} onChange={(v) => set({ foodPct: v })} />
        </div>
        {COST_FIELDS.map(([k, labelKey, hintKey]) => (
          <InvCategory key={k} label={t("fin." + labelKey)}
            hint={t("fin." + hintKey)}
            value={state[k] || 0}
            items={(state.costItems || {})[k] || []}
            onValue={(v) => set({ [k]: v })}
            onItems={(items) => set({ costItems: { ...state.costItems, [k]: items } })}
            suggestions={(COST_SUGGEST[k] && COST_SUGGEST[k][lang]) || []}
            meta={share(live.costs[k])} />
        ))}
        <TotalRow label={t("fin.totalMonthlyCost")} value={fmtBaht(live.totalCost)} />
      </div>
      <div style={{ marginTop: 16, padding: "16px 20px", borderRadius: 14, background: toneVar(live.netProfit >= 0 ? "green" : "red", "bg"), border: `1px solid ${toneVar(live.netProfit >= 0 ? "green" : "red", "bd")}`, display: "flex", justifyContent: "space-between", alignItems: "center", gap: 12, flexWrap: "wrap" }}>
        <span>
          <span style={{ fontWeight: 600, fontSize: 15, display: "block" }}>{live.netProfit >= 0 ? t("fin.takeHomeAfterTax") : t("fin.shortfallAfterTax")}</span>
          <span style={{ fontSize: 12.5, color: "var(--muted)" }}>{t("fin.beforeTax", { x: (live.profitBeforeTax < 0 ? "−" : "") + fmtBaht(Math.abs(live.profitBeforeTax)) })}</span>
        </span>
        <span className="serif-fig" style={{ fontSize: 26, color: live.netProfit >= 0 ? "var(--green)" : "var(--red)" }}>{live.netProfit < 0 ? "−" : ""}{fmtBaht(Math.abs(live.netProfit))}</span>
      </div>
      {summary && (
        <PageSummary note={t("fin.stepSummaryNote")} items={[
          { label: t("fin.variableCosts"), value: money(live.foodCost), sub: t("fin.moveWithSales") },
          { label: t("fin.fixedCosts"), value: money(live.fixed), sub: t("fin.sameEveryMonth") },
          { label: t("fin.breakEvenMo"), value: money(live.breakEven) },
          { label: t("fin.breakEvenDay"), value: money(live.breakEvenDaily) },
          { label: t("fin.ebitdaMo"), value: live.sales > 0 ? `${live.profit < 0 ? "−" : ""}${fmtBaht(Math.abs(live.profit))}` : "—", sub: live.sales > 0 ? t("fin.marginPreTax", { pct: fmtPct(live.margin) }) : null },
          { label: t("fin.netProfitAfterTax"), value: live.sales > 0 ? `${live.netProfit < 0 ? "−" : ""}${fmtBaht(Math.abs(live.netProfit))}` : "—", sub: live.sales > 0 ? t("fin.afterTaxMargin", { pct: fmtPct(live.netMargin) }) : null, tone: live.netProfit >= 0 ? "green" : "red" },
        ]} />
      )}
    </StepShell>
  );
}

/* ---------- results viz ---------- */
function StackedBar({ live }) {
  const segs = live.segs.filter((s) => s.pct > 0.001);
  const profitPct = Math.max(0, live.sales > 0 ? live.netProfit / live.sales : 0);
  const isLoss = live.netProfit < 0;
  return (
    <div style={{ display: "flex", height: 54, borderRadius: 12, overflow: "hidden", boxShadow: "inset 0 0 0 1px var(--border)" }}>
      {segs.map((s) => (
        <div key={s.key} title={`${s.label} ${fmtPct(s.pct)}`} style={{ width: `${Math.min(s.pct, 1) * 100}%`, background: s.color, borderRight: "1.5px solid rgba(255,255,255,.5)" }} />
      ))}
      {!isLoss && profitPct > 0 && <div style={{ width: `${profitPct * 100}%`, background: "var(--c-profit)" }} />}
    </div>
  );
}

function Donut({ live }) {
  const { t } = useLang();
  const segs = live.segs.filter((s) => s.pct > 0.001);
  const profitShare = live.sales > 0 ? live.netProfit / live.sales : 0;
  const all = [...segs, ...(profitShare > 0 ? [{ key: "profit", label: t("fin.profitKeep"), pct: profitShare, color: "var(--c-profit)" }] : [])];
  const total = all.reduce((a, b) => a + b.pct, 0) || 1;
  const R = 84, C = 2 * Math.PI * R; let acc = 0;
  return (
    <div style={{ position: "relative", width: 210, height: 210, flexShrink: 0 }}>
      <svg width="210" height="210" viewBox="0 0 210 210">
        <circle cx="105" cy="105" r={R} fill="none" stroke="var(--border)" strokeWidth="22"></circle>
        {all.map((s) => {
          const frac = s.pct / total, el = (
            <circle key={s.key} cx="105" cy="105" r={R} fill="none" stroke={s.color} strokeWidth="22"
              strokeDasharray={`${frac * C} ${C}`} strokeDashoffset={-acc * C} transform="rotate(-90 105 105)" strokeLinecap="butt"></circle>
          );
          acc += frac; return el;
        })}
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", textAlign: "center" }}>
        <div>
          <div className="mono" style={{ fontSize: 10.5, color: "var(--muted)", textTransform: "uppercase", letterSpacing: ".1em" }}>{t("fin.netMarginDonut")}</div>
          <div className="serif-fig" style={{ fontSize: 38, color: live.netProfit < 0 ? "var(--red)" : "var(--green)", lineHeight: 1.1 }}>{fmtPct(live.netMargin)}</div>
        </div>
      </div>
    </div>
  );
}

function BreakdownList({ live }) {
  const { t } = useLang();
  const Row = ({ color, label, pct, value, bold, tone }) => {
    const vc = tone === "green" ? "var(--green)" : tone === "red" ? "var(--red)" : "var(--ink)";
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 12, padding: "10px 0", borderTop: bold ? "1px solid var(--border)" : "none", marginTop: bold ? 4 : 0 }}>
        <span style={{ width: 11, height: 11, borderRadius: 3, background: color, flexShrink: 0 }} />
        <span style={{ flex: 1, fontWeight: bold ? 700 : 500, fontSize: 14.5, color: bold ? vc : "var(--ink)" }}>{label}</span>
        <span className="mono" style={{ width: 52, textAlign: "right", fontSize: 13, color: "var(--muted)" }}>{fmtPct(pct)}</span>
        <span className="serif-fig" style={{ width: 104, textAlign: "right", fontSize: bold ? 17 : 16, color: bold ? vc : "var(--ink)" }}>{value < 0 ? "−" : ""}฿{fmt(Math.abs(value))}</span>
      </div>
    );
  };
  return (
    <div>
      {live.segs.map((s) => <Row key={s.key} color={s.color} label={s.label} pct={s.pct} value={s.value} />)}
      <Row color="var(--c-profit)" label={live.netProfit >= 0 ? t("fin.profitKeep") : t("fin.monthlyLoss")} pct={live.sales > 0 ? live.netProfit / live.sales : 0} value={live.netProfit} bold tone={live.netProfit >= 0 ? "green" : "red"} />
    </div>
  );
}

function finVerdictBlurb(live, t) {
  if (live.sales <= 0) return t("fin.blurbEmpty");
  if (live.netProfit <= 0) return t("fin.blurbLoss", { x: fmtBaht(Math.abs(live.netProfit)) });
  if (live.netMargin < 0.12) return t("fin.blurbThin");
  return t("fin.blurbGood", { be: fmtBaht(live.breakEven), pb: fmtMonths(live.paybackAfterTax) });
}

function FinStepResults({ state, set, live, narrow, showSummary, coaching }) {
  const { t } = useLang();
  const v = live.verdict, tone = v.tone;
  return (
    <div style={{ animation: "fadeUp .45s cubic-bezier(.2,.7,.2,1)" }}>
      <div style={{ background: "var(--surface)", borderRadius: 20, padding: "4px 0 0", boxShadow: "var(--shadow-lg)", overflow: "hidden", border: "1px solid var(--border)" }}>
        <div style={{ height: 4, background: toneVar(tone, "fg") }} />
        <div style={{ padding: "26px 30px", display: "flex", alignItems: "flex-start", gap: 24, flexWrap: "wrap" }}>
          <div style={{ flex: 1, minWidth: 240 }}>
            <div className="mono" style={{ fontSize: 11, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--muted)", fontWeight: 600 }}>{t("fin.theVerdict")}</div>
            <div className="serif" style={{ fontSize: 46, color: toneVar(tone, "fg"), marginTop: 6, lineHeight: 1, letterSpacing: "-.02em" }}>{v.label}</div>
            <div style={{ fontSize: 15, color: "var(--ink)", marginTop: 12, opacity: .82, maxWidth: 440, lineHeight: 1.55 }}>{finVerdictBlurb(live, t)}</div>
          </div>
          <div style={{ textAlign: narrow ? "left" : "right" }}>
            <div className="mono" style={{ fontSize: 10.5, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--muted)" }}>{t("fin.netProfitMo")}</div>
            <div className="serif-fig" style={{ fontSize: 54, color: toneVar(tone, "fg"), lineHeight: 1.05, marginTop: 4 }}>{live.netProfit < 0 ? "−" : ""}{fmtBaht(Math.abs(live.netProfit))}</div>
            <div style={{ fontSize: 12.5, color: "var(--muted)", marginTop: 4 }}>{t("fin.preTaxTaxesEst", { x: (live.profit < 0 ? "−" : "") + fmtBaht(Math.abs(live.profit)), y: fmtBaht(live.taxTotal) })}</div>
          </div>
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))", gap: 14, marginTop: 16 }}>
        <Stat label={t("fin.netMargin")} value={fmtPct(live.netMargin)} sub={t("fin.afterTaxMarginSub")} tone={live.netMargin >= 0.12 ? "green" : live.netMargin > 0 ? "amber" : "red"} />
        <Stat label={t("fin.breakEvenSales")} value={fmtBaht(live.breakEven)} sub={t("fin.perDayShort", { x: fmt(live.breakEvenDaily) })} />
        <Stat label={t("fin.payback")} value={fmtMonths(live.paybackAfterTax)} sub={t("fin.paybackSub")} tone={isFinite(live.paybackAfterTax) && live.paybackAfterTax <= 36 ? "green" : "amber"} />
        <Stat label={t("fin.toOpen")} value={fmtBaht(live.investment)} sub={t("fin.totalUpfront")} />
      </div>

      <div style={{ ...card, marginTop: 16, padding: 28 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 16, flexWrap: "wrap" }}>
          <div style={{ flex: 1, minWidth: 240 }}>
            <h2 className="serif" style={{ fontSize: 26, fontWeight: 400, margin: 0, letterSpacing: "-.01em", lineHeight: 1.15 }}>{t("fin.whereEvery100")}</h2>
            <div style={{ color: "var(--muted)", fontSize: 14, marginTop: 8 }}>{t("fin.every100Desc")}</div>
          </div>
          <Segmented small value={state.chart} onChange={(c) => set({ chart: c })} options={[{ v: "bar", l: t("fin.bar") }, { v: "donut", l: t("fin.donut") }]} />
        </div>
        {state.chart === "donut" ? (
          <div style={{ display: "flex", gap: 40, alignItems: "center", flexWrap: "wrap", marginTop: 22 }}>
            <Donut live={live} />
            <div style={{ flex: 1, minWidth: 240 }}><BreakdownList live={live} /></div>
          </div>
        ) : (
          <div style={{ marginTop: 24 }}>
            <StackedBar live={live} />
            <div style={{ marginTop: 20 }}><BreakdownList live={live} /></div>
          </div>
        )}
      </div>

      {showSummary && <FinancialSummary live={live} />}

      {coaching && live.flags.length > 0 && (
        <div style={{ ...card, marginTop: 16, padding: 28 }}>
          <h2 className="serif" style={{ fontSize: 24, fontWeight: 400, margin: "0 0 16px" }}>{t("fin.whatToWatch")}</h2>
          <div style={{ display: "flex", flexDirection: "column", gap: 13 }}>{live.flags.map((f, i) => <Flag key={i} {...f} />)}</div>
        </div>
      )}
    </div>
  );
}

/* ---------- module wrapper ---------- */
function FinancialModule({ fin, setFin, idea, narrow, summary, coaching }) {
  const { t } = useLang();
  const FIN_STEPS = [t("fin.stepInvestment"), t("fin.stepSales"), t("fin.stepCosts"), t("fin.stepResults")];
  const set = (patch) => setFin(patch);
  const live = useMemoF(() => computeFin(fin, t), [fin, t]);
  const step = fin.step || 0;
  const setStep = (i) => set({ step: i });
  return (
    <div data-screen-label="Financial Feasibility">
      <div style={{ display: "flex", gap: 6, marginBottom: 28, flexWrap: "wrap" }}>
        {FIN_STEPS.map((s, i) => (
          <button key={s} onClick={() => setStep(i)} style={{
            border: "none", cursor: "pointer", borderRadius: 99, padding: "8px 16px",
            fontSize: 13, fontWeight: 600, fontFamily: "inherit", transition: "all .15s",
            background: i === step ? "var(--accent)" : "var(--surface)",
            color: i === step ? "#fff" : "var(--muted)",
            boxShadow: i === step ? "none" : "inset 0 0 0 1px var(--border)",
          }}>{i + 1} · {s}</button>
        ))}
      </div>

      {step === 0 && <FinStepInvestment state={fin} set={set} live={live} summary={summary} />}
      {step === 1 && <FinStepSales state={fin} set={set} live={live} summary={summary} idea={idea} />}
      {step === 2 && <FinStepCosts state={fin} set={set} live={live} summary={summary} />}
      {step === 3 && <FinStepResults state={fin} set={set} live={live} narrow={narrow} showSummary={summary} coaching={coaching} />}

      <div style={{ display: "flex", justifyContent: "space-between", marginTop: 28 }}>
        <button onClick={() => setStep(Math.max(0, step - 1))} style={{ ...btnGhost, visibility: step === 0 ? "hidden" : "visible" }}>{t("common.back")}</button>
        {step < 3 && <button onClick={() => setStep(step + 1)} style={btnPrimary}>{step === 2 ? t("fin.seeResults") : t("fin.continue")}</button>}
      </div>
    </div>
  );
}

Object.assign(window, { computeFin, FinancialModule });
