// Budget Tab — project-level + scope-level budgeting with full metric toggles
// Reuses SCOPES from ScopesOfWorkTab.jsx (loaded earlier)

const BUDGET_METRICS = [
  // Cost track
  { id: "originalCost", label: "Original Cost", group: "Cost", default: true, fmt: "money" },
  { id: "revisedCost", label: "Revised Cost", group: "Cost", default: true, fmt: "money" },
  { id: "forecastCost", label: "Forecast Cost", group: "Cost", default: true, fmt: "money" },
  { id: "actualCost", label: "Actual Cost", group: "Cost", default: true, fmt: "money" },
  { id: "committed", label: "Committed", group: "Cost", default: false, fmt: "money" },
  { id: "pending", label: "Pending", group: "Cost", default: false, fmt: "money" },
  { id: "remaining", label: "Cost Remaining", group: "Cost", default: true, fmt: "money" },
  { id: "eac", label: "EAC", group: "Cost", default: false, fmt: "money", help: "Estimated cost at completion" },
  // Revenue track
  { id: "originalRev", label: "Original Revenue", group: "Revenue", default: false, fmt: "money" },
  { id: "revisedRev", label: "Revised Revenue", group: "Revenue", default: true, fmt: "money" },
  { id: "forecastRev", label: "Forecast Revenue", group: "Revenue", default: false, fmt: "money" },
  { id: "earnedRev", label: "Earned Revenue", group: "Revenue", default: true, fmt: "money" },
  { id: "billed", label: "Billed to Date", group: "Revenue", default: true, fmt: "money" },
  { id: "remainingBill", label: "Remaining to Bill", group: "Revenue", default: false, fmt: "money" },
  // Change orders
  { id: "approvedCO", label: "Approved CO", group: "Change Orders", default: true, fmt: "money" },
  { id: "pendingCO", label: "Pending CO", group: "Change Orders", default: true, fmt: "money" },
  // Margin
  { id: "grossMargin", label: "Gross Margin", group: "Margin", default: true, fmt: "money" },
  { id: "marginPct", label: "Margin %", group: "Margin", default: true, fmt: "pct" },
  { id: "estProfit", label: "Est. Profit", group: "Margin", default: false, fmt: "money" },
  // Variance
  { id: "budgetVar", label: "Budget Variance", group: "Variance", default: true, fmt: "moneySigned" },
  { id: "forecastVar", label: "Forecast Variance", group: "Variance", default: false, fmt: "moneySigned" },
  { id: "pctComplete", label: "% Complete", group: "Variance", default: true, fmt: "pct" },
];

// Synthesize budget rows from SCOPES
const buildBudgetRows = (scopes) => scopes.map(s => {
  const originalCost = s.originalBudget;
  const revisedCost = s.revisedBudget;
  const forecastCost = s.forecast;
  const actualCost = s.actual;
  const committed = Math.round(originalCost * 0.62);
  const pending = Math.round(originalCost * 0.08);
  const remaining = Math.max(0, revisedCost - actualCost);
  const eac = Math.round(actualCost + remaining * 1.02);
  // Revenue side — derive from billable
  const originalRev = Math.round(originalCost * 1.22);
  const revisedRev = Math.round(s.billable);
  const forecastRev = Math.round(s.billable * 1.005);
  const earnedRev = Math.round(s.billable * (s.pct / 100));
  const billed = s.billed;
  const remainingBill = s.billable - s.billed;
  // CO breakdown
  const approvedCO = Math.round((revisedCost - originalCost) * 0.7);
  const pendingCO = Math.round((revisedCost - originalCost) * 0.3);
  // Margin
  const grossMargin = revisedRev - eac;
  const marginPct = revisedRev > 0 ? (grossMargin / revisedRev) * 100 : 0;
  const estProfit = forecastRev - eac;
  // Variance
  const budgetVar = actualCost - revisedCost;
  const forecastVar = forecastCost - revisedCost;

  return {
    id: s.id, number: s.number, name: s.name, status: s.status, statusTone: s.statusTone, owner: s.owner,
    pctComplete: s.pct,
    originalCost, revisedCost, forecastCost, actualCost, committed, pending, remaining, eac,
    originalRev, revisedRev, forecastRev, earnedRev, billed, remainingBill,
    approvedCO, pendingCO, grossMargin, marginPct, estProfit,
    budgetVar, forecastVar,
  };
});

const fmtCell = (val, fmt) => {
  if (val === null || val === undefined) return "—";
  if (fmt === "money") return fmtMoney(val);
  if (fmt === "moneySigned") {
    if (val === 0) return fmtMoney(0);
    return (val > 0 ? "+" : "−") + fmtMoney(Math.abs(val));
  }
  if (fmt === "pct") return `${Math.round(val)}%`;
  return val;
};

const cellTone = (id, val) => {
  if (id === "budgetVar" || id === "forecastVar") {
    if (val > 0) return "rgb(192,47,50)";
    if (val < 0) return "rgb(34,134,58)";
  }
  if (id === "marginPct") {
    if (val < 15) return "rgb(192,47,50)";
    if (val < 22) return "rgb(178,121,26)";
    return "rgb(34,134,58)";
  }
  if (id === "pendingCO" && val > 0) return "rgb(178,121,26)";
  return "rgb(26,27,37)";
};

const BudgetTab = ({ p }) => {
  const [view, setView] = React.useState("scope"); // "project" | "scope"
  const [activeMetrics, setActiveMetrics] = React.useState(
    new Set(BUDGET_METRICS.filter(m => m.default).map(m => m.id))
  );
  const [groupCollapsed, setGroupCollapsed] = React.useState({});

  const rows = React.useMemo(() => buildBudgetRows(SCOPES), []);
  const visibleMetrics = BUDGET_METRICS.filter(m => activeMetrics.has(m.id));
  const [metricsOpen, setMetricsOpen] = React.useState(false);

  const toggleMetric = (id) => {
    const next = new Set(activeMetrics);
    if (next.has(id)) next.delete(id); else next.add(id);
    setActiveMetrics(next);
  };

  // Project-level totals
  const totals = rows.reduce((acc, r) => {
    BUDGET_METRICS.forEach(m => {
      if (m.fmt === "pct") return;
      acc[m.id] = (acc[m.id] || 0) + (r[m.id] || 0);
    });
    return acc;
  }, {});
  // Recompute weighted/derived totals
  totals.marginPct = totals.revisedRev > 0 ? (totals.grossMargin / totals.revisedRev) * 100 : 0;
  totals.pctComplete = Math.round(rows.reduce((s, r) => s + r.pctComplete * r.originalCost, 0) / rows.reduce((s, r) => s + r.originalCost, 0));

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      {/* Top control bar */}
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <ViewToggle value={view} onChange={setView} options={[
            { id: "project", label: "Project", icon: "briefcase" },
            { id: "scope", label: "By Scope", icon: "layers" },
          ]} />
          <span style={{ height: 22, width: 1, background: "rgb(227,229,232)" }} />
          <FilterPill2 label="Period" value="Cumulative" />
          <FilterPill2 label="Currency" value="USD" />
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
          <Button kind="ghost" size="sm" icon="refresh">Recalculate</Button>
          <Button kind="ghost" size="sm" icon="download">Export</Button>
          <Button kind="primary" size="sm" icon="pen">Edit Budget</Button>
        </div>
      </div>

      {/* Headline KPI strip */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 12 }}>
        <BudgetKPI label="Revised Cost Budget" value={fmtMoney(totals.revisedCost)} sub={`Original ${fmtMoney(totals.originalCost)}`} />
        <BudgetKPI label="Actual to Date" value={fmtMoney(totals.actualCost)} sub={`${Math.round(totals.actualCost/totals.revisedCost*100)}% of revised`} />
        <BudgetKPI label="Estimate at Completion" value={fmtMoney(totals.eac)} sub={
          <span style={{ color: totals.eac > totals.revisedCost ? "rgb(192,47,50)" : "rgb(34,134,58)" }}>
            {totals.eac > totals.revisedCost ? "+" : "−"}{fmtMoney(Math.abs(totals.eac - totals.revisedCost))} vs budget
          </span>
        } />
        <BudgetKPI label="Earned Revenue" value={fmtMoney(totals.earnedRev)} sub={`${fmtMoney(totals.billed)} billed`} />
        <BudgetKPI
          label="Gross Margin"
          value={`${totals.marginPct.toFixed(1)}%`}
          sub={`${fmtMoney(totals.grossMargin)} forecast`}
          accent={totals.marginPct < 15 ? "rgb(192,47,50)" : totals.marginPct < 22 ? "rgb(178,121,26)" : "rgb(34,134,58)"}
        />
      </div>

      {/* Cost vs Revenue summary bars */}
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
        <BudgetSummaryCard
          title="Cost Budget"
          accent="rgb(83,74,255)"
          rows={[
            { label: "Original Cost", value: totals.originalCost },
            { label: "Approved CO", value: totals.approvedCO, tone: "info" },
            { label: "Pending CO", value: totals.pendingCO, tone: "warning", dashed: true },
            { label: "Revised Budget", value: totals.revisedCost, bold: true },
            { label: "Actual Cost", value: totals.actualCost },
            { label: "Committed", value: totals.committed },
            { label: "Pending", value: totals.pending, tone: "warning" },
            { label: "Cost Remaining", value: totals.remaining, bold: true },
          ]}
          progressLabel={`Spent ${fmtMoney(totals.actualCost)} of ${fmtMoney(totals.revisedCost)}`}
          progress={totals.actualCost / totals.revisedCost}
          progressTone={totals.actualCost > totals.revisedCost ? "rgb(192,47,50)" : "rgb(83,74,255)"}
        />
        <BudgetSummaryCard
          title="Revenue & Margin"
          accent="rgb(34,134,58)"
          rows={[
            { label: "Revised Revenue", value: totals.revisedRev, bold: true },
            { label: "Forecast Revenue", value: totals.forecastRev },
            { label: "Earned Revenue", value: totals.earnedRev },
            { label: "Billed to Date", value: totals.billed },
            { label: "Remaining to Bill", value: totals.remainingBill, tone: "warning" },
            { label: "Forecast Cost (EAC)", value: totals.eac },
            { label: "Estimated Profit", value: totals.estProfit, bold: true },
            { label: "Margin %", value: totals.marginPct, fmt: "pct", bold: true,
              tone: totals.marginPct < 15 ? "danger" : totals.marginPct < 22 ? "warning" : "success" },
          ]}
          progressLabel={`Earned ${fmtMoney(totals.earnedRev)} of ${fmtMoney(totals.revisedRev)}`}
          progress={totals.earnedRev / totals.revisedRev}
          progressTone="rgb(34,134,58)"
        />
      </div>

      {/* Budget table — with collapsible Visible Metrics */}
      <Card padding={0}>
        <div style={{ padding: "12px 16px", display: "flex", alignItems: "center", justifyContent: "space-between", borderBottom: "1px solid rgb(239,240,242)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <span style={{ fontSize: 14, fontWeight: 600, whiteSpace: "nowrap" }}>{view === "project" ? "Project Roll-up" : "Scope Breakdown"}</span>
            <Chip tone="neutral">{view === "project" ? "1 row" : `${rows.length} scopes`}</Chip>
          </div>
          <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
            <button onClick={() => setMetricsOpen(!metricsOpen)} style={{
              height: 28, padding: "0 10px", borderRadius: 8,
              background: metricsOpen ? "rgb(232,233,246)" : "#fff",
              border: `1px solid ${metricsOpen ? "rgb(178,172,255)" : "rgb(213,219,225)"}`,
              color: metricsOpen ? "rgb(83,74,255)" : "rgb(65,69,82)",
              fontSize: 12, fontWeight: 500, fontFamily: "inherit", cursor: "pointer",
              display: "inline-flex", alignItems: "center", gap: 6, whiteSpace: "nowrap"
            }}>
              <Icon name="layers" size={12} />
              <span>Visible Metrics</span>
              <span style={{
                background: metricsOpen ? "rgb(83,74,255)" : "rgb(241,242,244)",
                color: metricsOpen ? "#fff" : "rgb(106,115,131)",
                fontSize: 11, fontWeight: 600, padding: "1px 6px", borderRadius: 9999, fontVariantNumeric: "tabular-nums"
              }}>{visibleMetrics.length}/{BUDGET_METRICS.length}</span>
              <Icon name={metricsOpen ? "expandUp" : "expandDown"} size={11} style={{ transition: "transform 220ms ease", transform: metricsOpen ? "rotate(0deg)" : "rotate(0deg)" }} />
            </button>
            <Button size="sm" kind="ghost" icon="filter">Filter</Button>
          </div>
        </div>

        <div style={{
          display: "grid",
          gridTemplateRows: metricsOpen ? "1fr" : "0fr",
          transition: "grid-template-rows 280ms cubic-bezier(.2,.8,.2,1)",
        }}>
          <div style={{ overflow: "hidden" }}>
            <div style={{
              borderBottom: "1px solid rgb(239,240,242)", background: "rgb(252,252,253)",
              opacity: metricsOpen ? 1 : 0,
              transform: metricsOpen ? "translateY(0)" : "translateY(-4px)",
              transition: "opacity 220ms ease, transform 280ms cubic-bezier(.2,.8,.2,1)",
              transitionDelay: metricsOpen ? "60ms" : "0ms"
            }}>
              <div style={{ padding: "10px 16px", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
                <span style={{ fontSize: 12, color: "rgb(106,115,131)" }}>Toggle which metrics appear as columns in the table below.</span>
                <div style={{ display: "flex", gap: 6 }}>
                  <Button size="xs" kind="ghost" onClick={() => setActiveMetrics(new Set(BUDGET_METRICS.filter(m => m.default).map(m => m.id)))}>Reset</Button>
                  <Button size="xs" kind="ghost" onClick={() => setActiveMetrics(new Set(BUDGET_METRICS.map(m => m.id)))}>Show all</Button>
                  <Button size="xs" kind="ghost" onClick={() => setActiveMetrics(new Set())}>Clear</Button>
                </div>
              </div>
              <div style={{ padding: "6px 16px 14px", display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: "6px 16px" }}>
                {["Cost", "Revenue", "Change Orders", "Margin", "Variance"].map(group => (
                  <div key={group} style={{ display: "flex", flexDirection: "column", gap: 6 }}>
                    <div style={{ fontSize: 10, fontWeight: 600, color: "rgb(106,115,131)", textTransform: "uppercase", letterSpacing: ".05em", marginBottom: 2 }}>{group}</div>
                    {BUDGET_METRICS.filter(m => m.group === group).map(m => (
                      <MetricToggle key={m.id} active={activeMetrics.has(m.id)} label={m.label} onClick={() => toggleMetric(m.id)} />
                    ))}
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>

        <BudgetTable rows={view === "project" ? [{
          id: "project", number: "—", name: p.name, status: p.status, statusTone: STATUS_TONES[p.status], owner: p.pm,
          ...totals,
        }] : rows} metrics={visibleMetrics} totals={totals} showFooter={view === "scope"} />
      </Card>
    </div>
  );
};

const ViewToggle = ({ value, onChange, options }) => (
  <div style={{ display: "inline-flex", padding: 3, background: "rgb(241,242,244)", borderRadius: 9999, gap: 2 }}>
    {options.map(o => {
      const active = value === o.id;
      return (
        <button key={o.id} onClick={() => onChange(o.id)} style={{
          height: 26, padding: "0 12px", border: 0, borderRadius: 9999,
          background: active ? "#fff" : "transparent",
          boxShadow: active ? "0 1px 2px rgba(0,0,0,.06)" : "none",
          color: active ? "rgb(26,27,37)" : "rgb(106,115,131)",
          fontSize: 12, fontWeight: 600, cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 5, fontFamily: "inherit",
          whiteSpace: "nowrap"
        }}>
          <Icon name={o.icon} size={12} />
          {o.label}
        </button>
      );
    })}
  </div>
);

const FilterPill2 = ({ label, value }) => (
  <button style={{
    height: 28, padding: "0 10px", borderRadius: 9999,
    background: "#fff", border: "1px solid rgb(213,219,225)",
    color: "rgb(65,69,82)", fontSize: 12, fontWeight: 500, cursor: "pointer",
    display: "inline-flex", alignItems: "center", gap: 5, fontFamily: "inherit"
  }}>
    <span style={{ color: "rgb(106,115,131)" }}>{label}:</span>
    <span style={{ color: "rgb(26,27,37)", fontWeight: 600 }}>{value}</span>
    <Icon name="expandDown" size={11} />
  </button>
);

const BudgetKPI = ({ label, value, sub, accent }) => (
  <div style={{ background: "#fff", border: "1px solid rgb(227,229,232)", borderRadius: 12, padding: "14px 16px" }}>
    <div style={{ fontSize: 11, color: "rgb(106,115,131)", fontWeight: 500, textTransform: "uppercase", letterSpacing: ".04em", marginBottom: 6 }}>{label}</div>
    <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: "-.015em", fontVariantNumeric: "tabular-nums", color: accent || "rgb(26,27,37)" }}>{value}</div>
    <div style={{ fontSize: 12, color: "rgb(106,115,131)", marginTop: 4, fontVariantNumeric: "tabular-nums" }}>{sub}</div>
  </div>
);

const BudgetSummaryCard = ({ title, accent, rows, progressLabel, progress, progressTone }) => (
  <div style={{ background: "#fff", border: "1px solid rgb(227,229,232)", borderRadius: 12, overflow: "hidden" }}>
    <div style={{ padding: "12px 18px", display: "flex", alignItems: "center", gap: 8, borderBottom: "1px solid rgb(239,240,242)" }}>
      <span style={{ width: 6, height: 6, borderRadius: "50%", background: accent, flexShrink: 0 }} />
      <span style={{ fontSize: 14, fontWeight: 600, whiteSpace: "nowrap" }}>{title}</span>
    </div>
    <div style={{ padding: "8px 18px" }}>
      {rows.map((r, i) => (
        <div key={i} style={{
          display: "flex", justifyContent: "space-between", alignItems: "center", gap: 12,
          padding: "7px 0",
          borderBottom: i < rows.length - 1 ? `1px ${r.dashed ? "dashed" : "solid"} rgb(243,244,247)` : "none",
          fontWeight: r.bold ? 600 : 400,
        }}>
          <span style={{ fontSize: 13, color: r.bold ? "rgb(26,27,37)" : "rgb(65,69,82)", whiteSpace: "nowrap" }}>{r.label}</span>
          <span style={{
            fontSize: r.bold ? 14 : 13, fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap",
            color: r.tone === "danger" ? "rgb(192,47,50)" :
                   r.tone === "warning" ? "rgb(178,121,26)" :
                   r.tone === "success" ? "rgb(34,134,58)" :
                   r.tone === "info" ? "rgb(83,74,255)" :
                   "rgb(26,27,37)"
          }}>
            {r.fmt === "pct" ? `${r.value.toFixed(1)}%` : (r.value < 0 ? `−${fmtMoney(Math.abs(r.value))}` : fmtMoney(r.value))}
          </span>
        </div>
      ))}
    </div>
    <div style={{ padding: "12px 18px 16px", borderTop: "1px solid rgb(239,240,242)", background: "rgb(252,252,253)" }}>
      <div style={{ fontSize: 11, color: "rgb(106,115,131)", marginBottom: 6, fontVariantNumeric: "tabular-nums" }}>{progressLabel}</div>
      <ProgressBar value={Math.min(progress * 100, 100)} color={progressTone} height={6} />
    </div>
  </div>
);

const MetricToggle = ({ active, label, onClick }) => (
  <button onClick={onClick} style={{
    display: "flex", alignItems: "center", gap: 6, padding: "4px 6px",
    border: 0, background: "transparent", cursor: "pointer", fontFamily: "inherit",
    textAlign: "left", borderRadius: 4
  }}
  onMouseEnter={e => e.currentTarget.style.background = "rgb(248,248,251)"}
  onMouseLeave={e => e.currentTarget.style.background = "transparent"}>
    <span style={{
      width: 14, height: 14, borderRadius: 3,
      border: `1.5px solid ${active ? "rgb(83,74,255)" : "rgb(213,219,225)"}`,
      background: active ? "rgb(83,74,255)" : "#fff",
      display: "inline-flex", alignItems: "center", justifyContent: "center", flexShrink: 0
    }}>
      {active && <Icon name="check" size={9} color="#fff" />}
    </span>
    <span style={{ fontSize: 12, color: active ? "rgb(26,27,37)" : "rgb(65,69,82)", fontWeight: active ? 500 : 400 }}>{label}</span>
  </button>
);

const BudgetTable = ({ rows, metrics, totals, showFooter }) => {
  const cols = [
    { id: "name", label: "Scope", sticky: true, width: 280 },
    { id: "pctComplete", label: "%", width: 64, align: "right" },
    ...metrics.map(m => ({ ...m, width: m.fmt === "pct" ? 80 : 120, align: "right" })),
  ];
  const totalWidth = cols.reduce((s, c) => s + c.width, 0);

  return (
    <div style={{ overflowX: "auto" }}>
      <div style={{ minWidth: totalWidth }}>
        {/* Header */}
        <div style={{
          display: "grid", gridTemplateColumns: cols.map(c => `${c.width}px`).join(" "),
          padding: "10px 0", background: "rgb(252,252,253)", borderBottom: "1px solid rgb(239,240,242)",
          fontSize: 11, fontWeight: 600, color: "rgb(106,115,131)", textTransform: "uppercase", letterSpacing: ".04em", position: "sticky", top: 0
        }}>
          {cols.map((c, i) => (
            <div key={c.id} style={{
              padding: i === 0 ? "0 16px" : "0 12px",
              textAlign: c.align || "left",
              position: c.sticky ? "sticky" : "static",
              left: c.sticky ? 0 : undefined,
              background: c.sticky ? "rgb(252,252,253)" : undefined,
              zIndex: c.sticky ? 2 : 1,
              whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
            }}>{c.label}</div>
          ))}
        </div>

        {/* Body rows */}
        {rows.map((r, idx) => (
          <div key={r.id} style={{
            display: "grid", gridTemplateColumns: cols.map(c => `${c.width}px`).join(" "),
            padding: "12px 0", borderBottom: "1px solid rgb(239,240,242)", alignItems: "center",
            fontSize: 13,
            background: "#fff",
          }}
          onMouseEnter={e => e.currentTarget.style.background = "rgb(252,252,253)"}
          onMouseLeave={e => e.currentTarget.style.background = "#fff"}>
            {/* Scope name (sticky) */}
            <div style={{
              padding: "0 16px", position: "sticky", left: 0, background: "inherit", zIndex: 1,
              display: "flex", alignItems: "center", gap: 10, minWidth: 0
            }}>
              <span style={{ fontSize: 11, color: "rgb(106,115,131)", fontVariantNumeric: "tabular-nums", fontWeight: 500, flexShrink: 0 }}>{r.number}</span>
              <div style={{ minWidth: 0, flex: 1 }}>
                <div style={{ fontWeight: 500, color: "rgb(26,27,37)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.name}</div>
                <div style={{ display: "flex", alignItems: "center", gap: 6, marginTop: 2 }}>
                  <Chip tone={r.statusTone} dot>{r.status}</Chip>
                  <Avatar size={14} initials={r.owner.initials} color={r.owner.color} />
                </div>
              </div>
            </div>
            {/* % Complete with mini bar */}
            <div style={{ padding: "0 12px", textAlign: "right" }}>
              <div style={{ fontVariantNumeric: "tabular-nums", fontWeight: 600 }}>{Math.round(r.pctComplete)}%</div>
              <ProgressBar value={r.pctComplete} color={r.pctComplete === 100 ? "rgb(34,134,58)" : "rgb(83,74,255)"} height={3} />
            </div>
            {/* Metric cells */}
            {metrics.map(m => (
              <div key={m.id} style={{
                padding: "0 12px", textAlign: "right",
                fontVariantNumeric: "tabular-nums",
                color: cellTone(m.id, r[m.id]),
                fontWeight: m.id === "marginPct" || m.id === "budgetVar" ? 600 : 400,
              }}>
                {fmtCell(r[m.id], m.fmt)}
              </div>
            ))}
          </div>
        ))}

        {/* Footer (totals) */}
        {showFooter && (
          <div style={{
            display: "grid", gridTemplateColumns: cols.map(c => `${c.width}px`).join(" "),
            padding: "12px 0", background: "rgb(248,248,251)", borderTop: "2px solid rgb(213,219,225)",
            fontSize: 13, fontWeight: 600, alignItems: "center"
          }}>
            <div style={{ padding: "0 16px", position: "sticky", left: 0, background: "rgb(248,248,251)", zIndex: 1 }}>
              Project Total
            </div>
            <div style={{ padding: "0 12px", textAlign: "right", fontVariantNumeric: "tabular-nums" }}>{Math.round(totals.pctComplete)}%</div>
            {metrics.map(m => (
              <div key={m.id} style={{
                padding: "0 12px", textAlign: "right", fontVariantNumeric: "tabular-nums",
                color: cellTone(m.id, totals[m.id])
              }}>
                {fmtCell(totals[m.id], m.fmt)}
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

window.BudgetTab = BudgetTab;
