// Ops pages: Inventory, Supply Chain, Service Productivity, Exceptions Inbox

const { useState: useStateO, useMemo: useMemoO } = React;

// ────────────────────────────────────────────────────────────────────────
// INVENTORY
// ────────────────────────────────────────────────────────────────────────
function InventoryPage({ data }) {
  const { products } = data;
  const [filter, setFilter] = useStateO("all");
  const [sortBy, setSortBy] = useStateO("value");

  const enriched = products.map(p => {
    const value = p.stock * p.cost;
    const sellRate = p.velocity === "fast" ? 14 : p.velocity === "steady" ? 6 : p.velocity === "slow" ? 1.2 : 0.4;
    const monthsOnHand = p.stock / (sellRate * 30 / 30); // rough
    const stockoutDays = p.stock / sellRate;
    return { ...p, value, sellRate, monthsOnHand, stockoutDays };
  });

  const filtered = filter === "all" ? enriched :
    filter === "slow" ? enriched.filter(p => p.velocity === "slow" || p.velocity === "dead") :
    filter === "low" ? enriched.filter(p => p.stock < p.minStock) :
    filter === "fast" ? enriched.filter(p => p.velocity === "fast") : enriched;

  const sorted = [...filtered].sort((a,b) => b[sortBy] - a[sortBy]);

  const totalValue = enriched.reduce((s, p) => s + p.value, 0);
  const slowValue = enriched.filter(p => p.velocity === "slow" || p.velocity === "dead").reduce((s, p) => s + p.value, 0);
  const stockouts = enriched.filter(p => p.stock < p.minStock).length;

  return (
    <div className="pc-page">
      <div className="pc-kpi-grid pc-kpi-grid-4">
        <KPICard label="Inventory value (at cost)" value={fmtUSD(totalValue, { compact: true })} delta={3.2} sub="vs. last month" accent="var(--accent)" />
        <KPICard label="GMROI"  value="2.84"  delta={4.1}  hint="GP $ ÷ avg inventory" accent="var(--positive)" />
        <KPICard label="Inventory turns" value="4.2x" delta={-2.1} hint="Annualized" accent="var(--warning)" />
        <KPICard label="Slow/dead capital" value={fmtUSD(slowValue, { compact: true })} hint={`${(slowValue/totalValue*100).toFixed(0)}% of inventory value`} accent="var(--danger)" />
      </div>

      <div className="pc-ai-banner">
        <div style={{ display: "flex", alignItems: "flex-start", gap: 14, flex: 1 }}>
          <div style={{ width: 36, height: 36, borderRadius: 10, background: "radial-gradient(circle at 30% 30%, var(--accent), var(--accent-2))", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
            <Icon d={icons.ai} size={18} stroke="var(--on-accent)" strokeWidth={2.4} />
          </div>
          <div>
            <div style={{ fontSize: 11, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.6, marginBottom: 3 }}>Inventory health</div>
            <div style={{ fontSize: 14, color: "var(--text)", lineHeight: 1.5 }}>
              <b style={{ color: "var(--danger)" }}>$69K of working capital</b> is parked in Solas line (14 months on hand). A targeted liquidation through Channel B at 35% off would recover ~$46K in 7 months — and free buy budget for the <b style={{ color: "var(--warning)" }}>Polaris Beacon stockout in 11 days</b>.
            </div>
          </div>
        </div>
        <button className="pc-btn-mini">Build liquidation plan</button>
      </div>

      <div className="pc-section-tabs">
        {[
          { k: "all",  l: "All products" },
          { k: "low",  l: "Below safety stock" },
          { k: "slow", l: "Slow / dead stock" },
          { k: "fast", l: "Fast movers" },
        ].map(t => (
          <button key={t.k} className={filter === t.k ? "active" : ""} onClick={() => setFilter(t.k)}>
            {t.l}
            {t.k === "low" && stockouts > 0 && <span className="pc-tab-count">{stockouts}</span>}
          </button>
        ))}
        <div style={{ flex: 1 }} />
        <ExportButton rows={sorted} filename={"Inventory_" + filter} />
        <div className="pc-seg-sm">
          {[
            { k: "value", l: "Sort by value" },
            { k: "stock", l: "Stock" },
            { k: "stockoutDays", l: "Days of supply" },
          ].map(s => <button key={s.k} className={sortBy === s.k ? "active" : ""} onClick={() => setSortBy(s.k)}>{s.l}</button>)}
        </div>
      </div>

      <Card padding={0}>
        <table className="pc-table">
          <thead>
            <tr>
              <th>SKU</th>
              <th>Product</th>
              <th>Category</th>
              <th style={{textAlign:"right"}}>Stock</th>
              <th style={{textAlign:"right"}}>Min</th>
              <th>Coverage</th>
              <th style={{textAlign:"right"}}>Unit cost</th>
              <th style={{textAlign:"right"}}>Unit price</th>
              <th style={{textAlign:"right"}}>Margin</th>
              <th style={{textAlign:"right"}}>Days of supply</th>
              <th style={{textAlign:"right"}}>Value at cost</th>
              <th>Velocity</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            {sorted.map((p, i) => {
              const cov = p.stock / p.minStock;
              const status = p.stock < p.minStock ? "stockout" : p.velocity === "dead" ? "dead" : p.velocity === "slow" ? "slow" : "ok";
              const margin = ((p.price - p.cost) / p.price) * 100;
              return (
                <tr key={i} className={status === "stockout" ? "pc-row-danger" : status === "dead" ? "pc-row-muted" : ""}>
                  <td style={{paddingLeft:14, fontFamily:"ui-monospace, monospace", fontSize: 11.5, color: "var(--text-2)"}}>{p.sku}</td>
                  <td style={{fontWeight: 500}}>{p.name}</td>
                  <td><span className="pc-chip">{p.category}</span></td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{p.stock}</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: "var(--text-3)"}}>{p.minStock}</td>
                  <td>
                    <Bullet value={Math.min(cov, 3)} target={1} max={3} accent={cov < 1 ? "var(--danger)" : cov < 1.5 ? "var(--warning)" : "var(--positive)"} />
                  </td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{fmtUSD(p.cost)}</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: "var(--text-2)"}}>{fmtUSD(p.price)}</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: margin >= 50 ? "var(--positive)" : margin >= 30 ? "var(--warning)" : "var(--danger)"}}>{margin.toFixed(1)}%</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: p.stockoutDays < 14 ? "var(--danger)" : p.stockoutDays > 180 ? "var(--warning)" : "var(--text-2)"}}>{Math.round(p.stockoutDays)}d</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", fontWeight: 500}}>{fmtUSD(p.value, { compact: true })}</td>
                  <td><VelocityChip v={p.velocity} /></td>
                  <td><StatusChip s={status} /></td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </Card>

      {/* Inventory Movement Report */}
      <InventoryMovementCard data={data} />

      {/* Landed Cost Reconciliation */}
      <LandedCostReconciliation data={data} />

      <div className="pc-grid-2">
        <Card title="ABC analysis" subtitle="Pareto distribution by revenue contribution">
          <div style={{ padding: "8px 0" }}>
            {[
              { c: "A items (top 20%)", val: "82%", count: "3 SKUs", color: "var(--accent)" },
              { c: "B items (next 30%)", val: "14%", count: "4 SKUs", color: "var(--accent-2)" },
              { c: "C items (bottom 50%)", val: "4%", count: "5 SKUs", color: "var(--text-4)" },
            ].map((b, i) => (
              <div key={i} style={{ marginBottom: 12 }}>
                <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12, marginBottom: 6 }}>
                  <span>{b.c} <span style={{ color: "var(--text-3)" }}>· {b.count}</span></span>
                  <span style={{ fontFamily: "ui-monospace, monospace", fontWeight: 500 }}>{b.val} of revenue</span>
                </div>
                <div style={{ height: 6, background: "var(--grid)", borderRadius: 1 }}>
                  <div style={{ width: b.val, height: "100%", background: b.color, borderRadius: 1 }} />
                </div>
              </div>
            ))}
          </div>
          <AIInsight>
            Stock-keeping focus should follow 80/20: lock in service on A items, run B items lean, actively liquidate C inactivity.
          </AIInsight>
        </Card>

        <Card title="Inventory turnover · 12 months">
          <AreaChart
            height={220}
            labels={["Jun","Jul","Aug","Sep","Oct","Nov","Dec","Jan","Feb","Mar","Apr","May"]}
            yFmt={(v) => v.toFixed(1) + "x"}
            series={[
              { name: "Actual",  values: [3.8, 4.0, 4.1, 4.2, 4.3, 4.4, 4.3, 4.4, 4.3, 4.4, 4.3, 4.2], color: "var(--accent)" },
              { name: "Target",  values: Array(12).fill(5.0), color: "var(--positive)", fill: false, dashed: true },
            ]}
          />
        </Card>
      </div>
    </div>
  );
}

function VelocityChip({ v }) {
  const map = {
    fast:   { c: "var(--positive)", l: "Fast", b: "rgba(110,231,183,0.10)" },
    steady: { c: "var(--accent-2)", l: "Steady", b: "rgba(99,102,241,0.10)" },
    slow:   { c: "var(--warning)",  l: "Slow", b: "rgba(251,191,36,0.10)" },
    dead:   { c: "var(--danger)",   l: "Dead",   b: "rgba(248,113,113,0.10)" },
  };
  const m = map[v] || map.steady;
  return <span className="pc-statpill" style={{ color: m.c, background: m.b }}>{m.l}</span>;
}
function StatusChip({ s }) {
  const map = {
    stockout: { c: "var(--danger)", l: "Below safety", b: "rgba(248,113,113,0.10)" },
    dead:     { c: "rgba(148,163,184,0.9)", l: "Liquidate", b: "rgba(148,163,184,0.10)" },
    slow:     { c: "var(--warning)", l: "Watch", b: "rgba(251,191,36,0.10)" },
    ok:       { c: "var(--positive)", l: "Healthy", b: "rgba(110,231,183,0.10)" },
  };
  const m = map[s] || map.ok;
  return <span className="pc-statpill" style={{ color: m.c, background: m.b }}>{m.l}</span>;
}

// ─── Inventory Movement (period-aware) ─────────────────────────────────
function InventoryMovementCard({ data }) {
  const [win, setWin] = useStateO("30d");
  const factor = { "30d": 1, "60d": 2, "90d": 3, "Custom": 1 }[win] || 1;
  const rows = (data.inventoryMovement || []).map(m => ({
    ...m,
    inQty: Math.round(m.inQty * factor),
    outQty: Math.round(m.outQty * factor),
    transferIn: Math.round(m.transferIn * factor),
    transferOut: Math.round(m.transferOut * factor),
    scrap: Math.round(m.scrap * factor),
    beg: m.beg,
    ending: m.beg + Math.round(m.inQty * factor) - Math.round(m.outQty * factor) + Math.round(m.transferIn * factor) - Math.round(m.transferOut * factor) - Math.round(m.scrap * factor),
  }));
  return (
    <Card title="Inventory movement report" subtitle={"Beginning · Receipts · Shipments · Transfers · Scrap · Ending — last " + win}
          action={
            <div style={{ display: "flex", gap: 8 }}>
              <SegSmall opts={["30d","60d","90d","Custom"]} value={win} onChange={setWin} />
              <ExportButton rows={rows} filename={"Inventory_movement_" + win} />
            </div>
          } padding={0}>
      <table className="pc-table">
        <thead>
          <tr>
            <th>SKU</th><th>Product</th>
            <th style={{textAlign:"right"}}>Beg qty</th>
            <th style={{textAlign:"right"}}>Receipts</th>
            <th style={{textAlign:"right"}}>Shipments</th>
            <th style={{textAlign:"right"}}>Transfer in</th>
            <th style={{textAlign:"right"}}>Transfer out</th>
            <th style={{textAlign:"right"}}>Scrap / W-off</th>
            <th style={{textAlign:"right"}}>Ending qty</th>
            <th style={{textAlign:"right"}}>Net Δ</th>
            <th>Turn rate</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((m, i) => {
            const prod = data.products.find(p => p.sku === m.sku) || {};
            const netDelta = m.ending - m.beg;
            const turnRate = m.outQty / Math.max(((m.beg + m.ending) / 2), 1);
            return (
              <tr key={i} className={m.scrap > 4 ? "pc-row-danger" : ""}>
                <td style={{paddingLeft:14, fontFamily: "ui-monospace, monospace", fontSize: 11.5, color: "var(--text-2)"}}>{m.sku}</td>
                <td style={{fontSize: 12, fontWeight: 500}}>{prod.name || ""}</td>
                <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", color: "var(--text-3)"}}>{m.beg}</td>
                <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", color: m.inQty > 0 ? "var(--positive)" : "var(--text-3)"}}>+{m.inQty}</td>
                <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", color: "var(--accent-2)"}}>−{m.outQty}</td>
                <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", color: "var(--text-2)"}}>{m.transferIn ? "+" + m.transferIn : "—"}</td>
                <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", color: "var(--text-2)"}}>{m.transferOut ? "−" + m.transferOut : "—"}</td>
                <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", color: m.scrap > 0 ? "var(--danger)" : "var(--text-3)"}}>{m.scrap > 0 ? "−" + m.scrap : "—"}</td>
                <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", fontWeight: 500}}>{m.ending}</td>
                <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", color: netDelta >= 0 ? "var(--positive)" : "var(--danger)"}}>{netDelta >= 0 ? "+" : ""}{netDelta}</td>
                <td><Bullet value={Math.min(turnRate * 4, 100)} target={50} max={100} accent={turnRate > 0.6 ? "var(--positive)" : turnRate > 0.2 ? "var(--warning)" : "var(--danger)"} /></td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </Card>
  );
}

// ─── Landed Cost Reconciliation ─────────────────────────────────────────
function LandedCostReconciliation({ data }) {
  const [win, setWin] = useStateO("This month");
  const winFactor = { "This month": 1, "Quarter": 3, "YTD": 5 }[win] || 1;
  // Build per-SKU landed-cost decomposition (booked vs actual from invoices)
  // Material = unit price from vendor invoice; Freight = allocation from forwarder bill;
  // Duty = customs; Other = broker fees, handling.
  const rows = data.products.map((p, i) => {
    // Mock invoice-derived components — varies by vendor and SKU
    const isImport = ["V-202", "V-205"].includes(p.vendor);
    const materialActual = p.cost * (0.66 + (i % 5) * 0.02); // 66-74% of cost
    const freightActual  = p.cost * (isImport ? 0.14 : 0.05);
    const dutyActual     = isImport ? p.cost * 0.06 : 0;
    const otherActual    = p.cost * (0.02 + (i % 3) * 0.01);
    // Synthetic drift — some SKUs have variance, V-201 lots most affected
    const drift = p.vendor === "V-201" ? 0.082 : (i % 4 === 0 ? 0.034 : (i % 7 === 0 ? -0.018 : 0.004));
    const actualLanded = (materialActual + freightActual + dutyActual + otherActual) * (1 + drift);
    const bookedCost = p.cost;
    const variance$ = actualLanded - bookedCost;
    const variancePct = (variance$ / bookedCost) * 100;
    const status = Math.abs(variancePct) < 1.5 ? "matched" : Math.abs(variancePct) < 4 ? "minor" : "exception";
    // Number of invoices linked
    const invoices = (isImport ? 3 + (i % 3) : 1 + (i % 2)) * winFactor;
    return {
      sku: p.sku, name: p.name, vendor: p.vendor,
      booked: bookedCost,
      material: Math.round(materialActual * 100) / 100,
      freight: Math.round(freightActual * 100) / 100,
      duty: Math.round(dutyActual * 100) / 100,
      other: Math.round(otherActual * 100) / 100,
      actual: Math.round(actualLanded * 100) / 100,
      variance$: Math.round(variance$ * 100) / 100,
      variancePct: Math.round(variancePct * 10) / 10,
      status,
      invoices,
    };
  });

  const exceptions = rows.filter(r => r.status === "exception");
  const minor = rows.filter(r => r.status === "minor");
  const totalVariance = rows.reduce((s, r) => {
    const product = data.products.find(p => p.sku === r.sku);
    return s + (r.variance$ * (product?.stock || 0));
  }, 0);

  return (
    <Card title="Landed cost reconciliation"
          subtitle="Booked unit cost vs actual landed cost from invoices · material + freight + duty + other"
          action={
            <div style={{ display: "flex", gap: 8 }}>
              <SegSmall opts={["This month","Quarter","YTD"]} value={win} onChange={setWin} />
              <ExportButton rows={rows} filename={"Landed_cost_reconciliation_" + win} />
            </div>
          } padding={0}>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 1, background: "var(--border)", borderBottom: "1px solid var(--border)" }}>
        <div className="pc-lcr-stat" style={{ background: "var(--bg-card-solid)" }}>
          <div className="pc-mk-l">SKUs reconciled</div>
          <div className="pc-mk-v">{rows.length}</div>
          <div className="pc-mk-d" style={{ color: "var(--text-3)" }}>last 30 days</div>
        </div>
        <div className="pc-lcr-stat" style={{ background: "var(--bg-card-solid)" }}>
          <div className="pc-mk-l">Matched</div>
          <div className="pc-mk-v" style={{ color: "var(--positive)" }}>{rows.filter(r => r.status === "matched").length}</div>
          <div className="pc-mk-d" style={{ color: "var(--text-3)" }}>within 1.5% tolerance</div>
        </div>
        <div className="pc-lcr-stat" style={{ background: "var(--bg-card-solid)" }}>
          <div className="pc-mk-l">Variances flagged</div>
          <div className="pc-mk-v" style={{ color: "var(--warning)" }}>{minor.length + exceptions.length}</div>
          <div className="pc-mk-d" style={{ color: "var(--text-3)" }}>{exceptions.length} over 4%</div>
        </div>
        <div className="pc-lcr-stat" style={{ background: "var(--bg-card-solid)" }}>
          <div className="pc-mk-l">Booked-value impact</div>
          <div className="pc-mk-v" style={{ color: totalVariance > 0 ? "var(--danger)" : "var(--positive)" }}>{totalVariance > 0 ? "+" : ""}{fmtUSD(totalVariance, { compact: true })}</div>
          <div className="pc-mk-d" style={{ color: "var(--text-3)" }}>if booked cost updated</div>
        </div>
      </div>

      <table className="pc-table">
        <thead>
          <tr>
            <th>SKU</th>
            <th>Vendor</th>
            <th style={{textAlign:"right"}}>Booked cost</th>
            <th style={{textAlign:"right"}}>Material</th>
            <th style={{textAlign:"right"}}>Freight</th>
            <th style={{textAlign:"right"}}>Duty</th>
            <th style={{textAlign:"right"}}>Other</th>
            <th style={{textAlign:"right"}}>Actual landed</th>
            <th style={{textAlign:"right"}}>Variance $</th>
            <th style={{textAlign:"right"}}>Variance %</th>
            <th>Invoices</th>
            <th>Status</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r, i) => {
            const isOver = r.variance$ > 0;
            return (
              <tr key={i} className={r.status === "exception" ? "pc-row-danger" : ""}>
                <td style={{paddingLeft:14}}>
                  <div style={{fontFamily:"ui-monospace, monospace", fontSize: 11.5, fontWeight: 500, color: "var(--text-2)"}}>{r.sku}</div>
                  <div style={{fontSize: 11, color: "var(--text-3)"}}>{r.name}</div>
                </td>
                <td style={{fontFamily: "ui-monospace, monospace", fontSize: 11, color: "var(--text-3)"}}>{r.vendor}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", fontWeight: 500}}>{fmtUSD(r.booked)}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: "var(--text-2)"}}>{fmtUSD(r.material)}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: "var(--text-2)"}}>{fmtUSD(r.freight)}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: "var(--text-2)"}}>{r.duty > 0 ? fmtUSD(r.duty) : "—"}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: "var(--text-2)"}}>{fmtUSD(r.other)}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", fontWeight: 500}}>{fmtUSD(r.actual)}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: isOver ? "var(--danger)" : r.variance$ < 0 ? "var(--positive)" : "var(--text-3)", fontWeight: r.status === "exception" ? 600 : 400}}>
                  {r.variance$ > 0 ? "+" : ""}{fmtUSD(r.variance$)}
                </td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: r.status === "exception" ? "var(--danger)" : r.status === "minor" ? "var(--warning)" : "var(--positive)"}}>
                  {r.variancePct > 0 ? "+" : ""}{r.variancePct.toFixed(1)}%
                </td>
                <td style={{fontFamily: "ui-monospace, monospace", fontSize: 11, color: "var(--text-3)"}}>{r.invoices} linked</td>
                <td><LandedStatusChip s={r.status} /></td>
              </tr>
            );
          })}
        </tbody>
      </table>

      {exceptions.length > 0 && (
        <div style={{ padding: "14px 18px", borderTop: "1px solid var(--border)", background: "rgba(248,113,113,0.04)" }}>
          <AIInsight>
            <b>{exceptions.length} SKU{exceptions.length !== 1 ? "s" : ""} flagged for landed-cost exception.</b> {exceptions[0]?.sku} ({exceptions[0]?.name}) is +{exceptions[0]?.variancePct.toFixed(1)}% over booked cost — vendor {exceptions[0]?.vendor} input price increased post-Apr 18 lots and the standard cost in your books hasn't been refreshed. <b>Recommended action: update standard cost on the {exceptions.length} SKU{exceptions.length !== 1 ? "s" : ""} to recover margin accuracy in your P&L</b> — impact ~{fmtUSD(Math.abs(totalVariance), { compact: true })} of booked inventory value.
          </AIInsight>
        </div>
      )}
    </Card>
  );
}

function LandedStatusChip({ s }) {
  const map = {
    matched:   { c: "var(--positive)", l: "Matched",   b: "rgba(110,231,183,0.10)" },
    minor:     { c: "var(--warning)",  l: "Review",    b: "rgba(251,191,36,0.10)" },
    exception: { c: "var(--danger)",   l: "Exception", b: "rgba(248,113,113,0.10)" },
  };
  const m = map[s] || map.matched;
  return <span className="pc-statpill" style={{ color: m.c, background: m.b }}>{m.l}</span>;
}

// ────────────────────────────────────────────────────────────────────────
// SUPPLY CHAIN
// ────────────────────────────────────────────────────────────────────────
function SupplyPage({ data }) {
  const { vendors, products } = data;

  return (
    <div className="pc-page">
      <div className="pc-kpi-grid pc-kpi-grid-4">
        <KPICard label="Active vendors" value={vendors.length} accent="var(--accent)" />
        <KPICard label="Avg lead time"   value={Math.round(vendors.reduce((s,v)=>s+v.leadTime,0)/vendors.length) + "d"} delta={-3.2} sub="vs last quarter" accent="var(--positive)" />
        <KPICard label="On-time delivery" value={(vendors.reduce((s,v)=>s+v.onTime,0)/vendors.length*100).toFixed(0) + "%"} delta={1.4} accent="var(--positive)" />
        <KPICard label="At-risk SKUs"    value={3} hint="Stockout in 30d" accent="var(--danger)" />
      </div>

        <Card title="Reorder recommendations" subtitle="AI-generated · ranked by stockout risk × revenue impact"
            action={<button className="pc-btn-mini" onClick={() => alert("Draft POs created — review in Open POs below")}>Generate POs</button>} padding={0}>
        <table className="pc-table">
          <thead>
            <tr>
              <th>SKU</th><th>Product</th><th>Vendor</th>
              <th style={{textAlign:"right"}}>On hand</th>
              <th style={{textAlign:"right"}}>Days left</th>
              <th style={{textAlign:"right"}}>Lead time</th>
              <th style={{textAlign:"right"}}>Reorder qty</th>
              <th style={{textAlign:"right"}}>PO value</th>
              <th>Recommendation</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {[
              { sku: "POL-550", name: "Polaris Beacon", vendor: "Shenzhen Forge", oh: 8, days: 11, lt: 45, qty: 48, val: 712 * 48, urgency: "critical", rec: "Air freight (+12d saved)" },
              { sku: "ORI-220", name: "Orion Module 4U", vendor: "Kanto Industrial", oh: 28, days: 18, lt: 38, qty: 120, val: 248 * 120, urgency: "high", rec: "Place this week" },
              { sku: "AUR-100", name: "Aurelius Pro Kit", vendor: "Tessera Materials", oh: 312, days: 67, lt: 14, qty: 80, val: 612 * 80, urgency: "medium", rec: "Standard reorder" },
              { sku: "VEL-310", name: "Vela Cable Loom", vendor: "Linde Components", oh: 412, days: 88, lt: 21, qty: 200, val: 22 * 200, urgency: "low", rec: "Combine w/ VEL-311" },
              { sku: "AUR-101", name: "Aurelius Lite", vendor: "Tessera Materials", oh: 144, days: 41, lt: 14, qty: 60, val: 384 * 60, urgency: "medium", rec: "Standard reorder" },
            ].map((r, i) => (
              <tr key={i} className={r.urgency === "critical" ? "pc-row-danger" : ""}>
                <td style={{paddingLeft:14, fontFamily:"ui-monospace, monospace", fontSize: 11.5, color: "var(--text-2)"}}>{r.sku}</td>
                <td style={{fontWeight:500}}>{r.name}</td>
                <td style={{color:"var(--text-2)"}}>{r.vendor}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{r.oh}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: r.days < 14 ? "var(--danger)" : r.days < 30 ? "var(--warning)" : "var(--text-2)"}}>{r.days}d</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color:"var(--text-2)"}}>{r.lt}d</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", fontWeight: 500}}>{r.qty}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", fontWeight: 500}}>{fmtUSD(r.val)}</td>
                <td style={{fontSize:11.5, color:"var(--text-2)"}}>{r.rec}</td>
                <td><SevPill sev={r.urgency} /></td>
              </tr>
            ))}
          </tbody>
        </table>
      </Card>

      <OpenPOsCard data={data} />

      <div className="pc-grid-2">
        <Card title="Vendor scorecard" subtitle="On-time delivery × lead time stability">
          <table className="pc-table compact">
            <thead><tr><th>Vendor</th><th>Country</th><th style={{textAlign:"right"}}>Lead time</th><th>On-time</th><th>Risk</th></tr></thead>
            <tbody>
              {vendors.map((v, i) => (
                <tr key={i}>
                  <td style={{paddingLeft:14, fontWeight:500}}>{v.name}</td>
                  <td style={{color:"var(--text-2)", fontSize: 11.5}}>{v.country}</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{v.leadTime}d</td>
                  <td><Bullet value={v.onTime * 100} target={90} max={100} accent={v.onTime >= 0.9 ? "var(--positive)" : v.onTime >= 0.85 ? "var(--warning)" : "var(--danger)"} /></td>
                  <td><SevPill sev={v.onTime < 0.85 ? "high" : v.onTime < 0.93 ? "medium" : "low"} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>

        <Card title="Lead time trend · key vendors">
          <AreaChart
            height={220}
            labels={["Jun","Jul","Aug","Sep","Oct","Nov","Dec","Jan","Feb","Mar","Apr","May"]}
            yFmt={(v) => v.toFixed(0) + "d"}
            series={[
              { name: "Shenzhen Forge", values: [38,40,42,42,44,45,46,46,45,45,46,45], color: "var(--danger)" },
              { name: "Kanto Industrial", values: [34,35,36,37,37,38,38,38,38,38,38,38], color: "var(--warning)", fill: false },
              { name: "Tessera Materials", values: [14,14,15,15,14,14,13,14,14,14,14,14], color: "var(--positive)", fill: false, dashed: true },
            ]}
          />
        </Card>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// OPEN POs — purchase order tracking + cash forecast + warehouse view
// ────────────────────────────────────────────────────────────────────────
function OpenPOsCard({ data }) {
  const today = new Date(2026, 4, 15); // May 15, 2026 mock
  const addDays = (d, n) => { const x = new Date(d); x.setDate(x.getDate() + n); return x; };
  const fmtDate = (d) => d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
  const daysBetween = (a, b) => Math.round((b - a) / 86400000);

  // Synthesize PO data tied to vendors + products
  const pos = [
    { poNum: "PO-2026-0184", vendor: "Tessera Materials",  vendorId: "V-201", country: "USA",   placed: addDays(today, -8),  eta: addDays(today, 6),   sku: "AUR-100", name: "Aurelius Pro Kit",   qty: 80,  unitCost: 612, freight: 1800, duty: 0,   terms: "Net 30", payDue: addDays(today, 22),  status: "In transit",      stage: "ocean" },
    { poNum: "PO-2026-0183", vendor: "Tessera Materials",  vendorId: "V-201", country: "USA",   placed: addDays(today, -12), eta: addDays(today, 2),   sku: "AUR-101", name: "Aurelius Lite",      qty: 60,  unitCost: 384, freight: 1100, duty: 0,   terms: "Net 30", payDue: addDays(today, 18),  status: "At port",          stage: "port" },
    { poNum: "PO-2026-0182", vendor: "Kanto Industrial",   vendorId: "V-202", country: "JPN",   placed: addDays(today, -25), eta: addDays(today, 13),  sku: "ORI-220", name: "Orion Module 4U",    qty: 120, unitCost: 248, freight: 4200, duty: 1840, terms: "Net 45", payDue: addDays(today, 20),  status: "In transit",      stage: "ocean" },
    { poNum: "PO-2026-0181", vendor: "Shenzhen Forge",     vendorId: "V-205", country: "CHN",   placed: addDays(today, -38), eta: addDays(today, 7),   sku: "POL-550", name: "Polaris Beacon",     qty: 48,  unitCost: 712, freight: 5600, duty: 2400, terms: "Net 60", payDue: addDays(today, 22),  status: "In transit · air", stage: "air" },
    { poNum: "PO-2026-0180", vendor: "Shenzhen Forge",     vendorId: "V-205", country: "CHN",   placed: addDays(today, -45), eta: addDays(today, -3),  sku: "POL-551", name: "Polaris Mount",      qty: 200, unitCost: 78,  freight: 2200, duty: 940,  terms: "Net 60", payDue: addDays(today, 15),  status: "Delayed",          stage: "ocean", delay: 5 },
    { poNum: "PO-2026-0179", vendor: "Linde Components",   vendorId: "V-203", country: "DEU",   placed: addDays(today, -16), eta: addDays(today, 5),   sku: "VEL-310", name: "Vela Cable Loom",    qty: 480, unitCost: 22,  freight: 1400, duty: 320,  terms: "Net 30", payDue: addDays(today, 14),  status: "In transit",      stage: "ocean" },
    { poNum: "PO-2026-0178", vendor: "Boreal Pulp",        vendorId: "V-204", country: "CAN",   placed: addDays(today, -6),  eta: addDays(today, 5),   sku: "MER-441", name: "Meridian Tote",      qty: 240, unitCost: 26,  freight: 480,  duty: 0,   terms: "Net 30", payDue: addDays(today, 24),  status: "Approved",         stage: "supplier" },
    { poNum: "PO-2026-0177", vendor: "Heritage Mills",     vendorId: "V-206", country: "USA",   placed: addDays(today, -3),  eta: addDays(today, 6),   sku: "SOL-670", name: "Solas Lamp",         qty: 80,  unitCost: 142, freight: 380,  duty: 0,   terms: "Net 30", payDue: addDays(today, 27),  status: "Approved",         stage: "supplier" },
    { poNum: "PO-2026-0176", vendor: "Kanto Industrial",   vendorId: "V-202", country: "JPN",   placed: addDays(today, -2),  eta: addDays(today, 36),  sku: "ORI-221", name: "Orion Module 2U",    qty: 80,  unitCost: 178, freight: 2900, duty: 1280, terms: "Net 45", payDue: addDays(today, 43),  status: "Pending approval", stage: "draft" },
  ];

  // Compute totals
  const enriched = pos.map(po => {
    const landed = (po.qty * po.unitCost) + po.freight + po.duty;
    const daysToETA = daysBetween(today, po.eta);
    const daysSincePlaced = daysBetween(po.placed, today);
    const daysToPay = daysBetween(today, po.payDue);
    return { ...po, landed, daysToETA, daysSincePlaced, daysToPay };
  });

  const totalOpen = enriched.reduce((s, p) => s + p.landed, 0);
  const inTransit = enriched.filter(p => p.stage === "ocean" || p.stage === "port" || p.stage === "air").reduce((s, p) => s + p.landed, 0);
  const cashNext30 = enriched.filter(p => p.daysToPay >= 0 && p.daysToPay <= 30).reduce((s, p) => s + p.landed, 0);
  const delayed = enriched.filter(p => p.status === "Delayed").length;

  // Stage flow visualization counts
  const stageCounts = {
    draft:    enriched.filter(p => p.stage === "draft").length,
    supplier: enriched.filter(p => p.stage === "supplier").length,
    ocean:    enriched.filter(p => p.stage === "ocean").length,
    air:      enriched.filter(p => p.stage === "air").length,
    port:     enriched.filter(p => p.stage === "port").length,
  };

  return (
    <>
      <div className="pc-kpi-grid pc-kpi-grid-4">
        <KPICard label="Open PO value"     value={fmtUSD(totalOpen, { compact: true })} hint={pos.length + " open POs"} accent="var(--accent)" />
        <KPICard label="In-transit value"  value={fmtUSD(inTransit, { compact: true })} hint="On water + air + at port" accent="var(--accent-2)" />
        <KPICard label="Payable in 30 days" value={fmtUSD(cashNext30, { compact: true })} hint="Hits cash forecast" accent="var(--warning)" />
        <KPICard label="Delayed POs"        value={delayed} hint={delayed > 0 ? "Action needed" : "All on schedule"} accent={delayed > 0 ? "var(--danger)" : "var(--positive)"} />
      </div>

      <Card title="PO pipeline" subtitle="From order placement to receipt — track where every dollar is in the chain">
        <div className="pc-po-pipeline">
          {[
            { k: "draft",    l: "Pending approval", count: stageCounts.draft,    color: "var(--text-3)" },
            { k: "supplier", l: "With supplier",    count: stageCounts.supplier, color: "var(--accent-2)" },
            { k: "ocean",    l: "On the water",     count: stageCounts.ocean,    color: "var(--warning)" },
            { k: "air",      l: "Air freight",      count: stageCounts.air,      color: "var(--accent)" },
            { k: "port",     l: "At port / customs", count: stageCounts.port,    color: "var(--accent-2)" },
          ].map((s, idx) => (
            <div key={s.k} className="pc-po-stage" style={{ borderTopColor: s.color }}>
              <div style={{ fontSize: 26, fontWeight: 700, fontFamily: "'Geist Mono', ui-monospace, monospace", color: s.color }}>{s.count}</div>
              <div style={{ fontSize: 11.5, color: "var(--text-2)", fontWeight: 500, marginTop: 2 }}>{s.l}</div>
              <div style={{ fontSize: 10.5, color: "var(--text-3)", marginTop: 6, fontFamily: "ui-monospace, monospace" }}>
                {fmtUSD(enriched.filter(p => p.stage === s.k).reduce((sum, p) => sum + p.landed, 0), { compact: true })}
              </div>
            </div>
          ))}
        </div>
      </Card>

      <Card title="Open purchase orders"
            subtitle="Live tracking · click any PO to see line items, vendor history, and link to AP"
            action={
              <div style={{ display: "flex", gap: 8 }}>
                <ExportButton rows={enriched.map(p => ({ PO: p.poNum, Vendor: p.vendor, SKU: p.sku, Product: p.name, Qty: p.qty, Placed: fmtDate(p.placed), ETA: fmtDate(p.eta), Status: p.status, LandedCost: p.landed, Terms: p.terms, PaymentDue: fmtDate(p.payDue) }))} filename="Open_purchase_orders" />
                <button className="pc-btn-mini" onClick={() => alert("Create PO form — coming soon")}>+ New PO</button>
              </div>
            } padding={0}>
        <table className="pc-table">
          <thead>
            <tr>
              <th>PO #</th>
              <th>Vendor</th>
              <th>Product</th>
              <th style={{textAlign:"right"}}>Qty</th>
              <th>Placed</th>
              <th>Expected arrival</th>
              <th style={{textAlign:"right"}}>Landed cost</th>
              <th>Terms</th>
              <th>Payment due</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            {enriched.map((p, i) => (
              <tr key={i} className={p.status === "Delayed" ? "pc-row-danger" : ""}>
                <td style={{paddingLeft: 14, fontFamily: "ui-monospace, monospace", fontSize: 11, color: "var(--text-2)", fontWeight: 500}}>{p.poNum}</td>
                <td>
                  <div style={{ fontSize: 12.5, fontWeight: 500 }}>{p.vendor}</div>
                  <div style={{ fontSize: 10.5, color: "var(--text-3)" }}>{p.country} · {p.vendorId}</div>
                </td>
                <td>
                  <div style={{ fontSize: 12.5, fontWeight: 500 }}>{p.name}</div>
                  <div style={{ fontSize: 10.5, color: "var(--text-3)", fontFamily: "ui-monospace, monospace" }}>{p.sku}</div>
                </td>
                <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", fontWeight: 500}}>{p.qty}</td>
                <td>
                  <div style={{ fontSize: 12, fontWeight: 500 }}>{fmtDate(p.placed)}</div>
                  <div style={{ fontSize: 10.5, color: "var(--text-3)" }}>{p.daysSincePlaced}d ago</div>
                </td>
                <td>
                  <div style={{ fontSize: 12, fontWeight: 500, color: p.daysToETA < 0 ? "var(--danger)" : "var(--text)" }}>{fmtDate(p.eta)}</div>
                  <div style={{ fontSize: 10.5, color: p.daysToETA < 0 ? "var(--danger)" : "var(--text-3)" }}>
                    {p.daysToETA < 0 ? Math.abs(p.daysToETA) + "d late" : "in " + p.daysToETA + "d"}
                  </div>
                </td>
                <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right"}}>
                  <div style={{ fontWeight: 600 }}>{fmtUSD(p.landed)}</div>
                  <div style={{ fontSize: 10, color: "var(--text-3)", marginTop: 2 }}>
                    +{fmtUSD(p.freight + p.duty, { compact: true })} fr/duty
                  </div>
                </td>
                <td><span className="pc-chip">{p.terms}</span></td>
                <td>
                  <div style={{ fontSize: 12, fontWeight: 500, color: p.daysToPay <= 7 ? "var(--warning)" : "var(--text)" }}>{fmtDate(p.payDue)}</div>
                  <div style={{ fontSize: 10.5, color: p.daysToPay <= 7 ? "var(--warning)" : "var(--text-3)" }}>
                    {p.daysToPay < 0 ? Math.abs(p.daysToPay) + "d overdue" : "in " + p.daysToPay + "d"}
                  </div>
                </td>
                <td><POStatusPill status={p.status} stage={p.stage} /></td>
              </tr>
            ))}
          </tbody>
        </table>
      </Card>

      <InboundTimelineCard enriched={enriched} />

      <div className="pc-grid-2">
        <Card title="Cash impact · next 60 days from POs" subtitle="When payment hits the bank">
          <table className="pc-table compact">
            <thead><tr><th>Week of</th><th style={{textAlign:"right"}}>Outflow</th><th>POs</th></tr></thead>
            <tbody>
              {Array.from({ length: 8 }, (_, w) => {
                const weekStart = addDays(today, w * 7);
                const weekEnd = addDays(today, (w + 1) * 7);
                const inWeek = enriched.filter(p => p.payDue >= weekStart && p.payDue < weekEnd);
                const sum = inWeek.reduce((s, p) => s + p.landed, 0);
                return { weekStart, sum, count: inWeek.length };
              }).filter(w => w.count > 0).map((w, i) => (
                <tr key={i}>
                  <td style={{paddingLeft: 14}}>{fmtDate(w.weekStart)}</td>
                  <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", color: w.sum > 50000 ? "var(--danger)" : "var(--text)", fontWeight: 500}}>−{fmtUSD(w.sum)}</td>
                  <td style={{fontSize: 11.5, color: "var(--text-3)"}}>{w.count} PO{w.count > 1 ? "s" : ""}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>

        <Card title="Warehouse inbound · arriving in 30 days" subtitle="Plan dock + storage capacity">
          <table className="pc-table compact">
            <thead><tr><th>SKU</th><th style={{textAlign:"right"}}>Units</th><th>Arrives</th><th>Method</th></tr></thead>
            <tbody>
              {enriched.filter(p => p.daysToETA >= 0 && p.daysToETA <= 30).sort((a, b) => a.daysToETA - b.daysToETA).map((p, i) => (
                <tr key={i}>
                  <td style={{paddingLeft: 14, fontFamily: "ui-monospace, monospace", fontSize: 11.5}}>{p.sku}</td>
                  <td style={{fontFamily: "ui-monospace, monospace", textAlign: "right", fontWeight: 500}}>{p.qty.toLocaleString()}</td>
                  <td style={{fontSize: 11.5}}>{fmtDate(p.eta)} <span style={{ color: "var(--text-3)" }}>({p.daysToETA}d)</span></td>
                  <td><span className="pc-chip" style={{ background: p.stage === "air" ? "rgba(110,231,183,0.10)" : p.stage === "ocean" ? "rgba(251,191,36,0.10)" : "var(--bg-elev-1)", color: p.stage === "air" ? "var(--positive)" : p.stage === "ocean" ? "var(--warning)" : "var(--text-2)" }}>{p.stage === "air" ? "Air" : p.stage === "ocean" ? "Ocean" : p.stage === "port" ? "Port" : "Ground"}</span></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
      </div>
    </>
  );
}

// ─── Stacked Timeline ──────────────────────────────────────────────────
function StackedTimeline({ buckets, cats, matrix, totals, maxTotal, colorFor, showMode }) {
  const ref = React.useRef(null);
  const [width, setWidth] = React.useState(800);
  React.useEffect(() => {
    if (!ref.current) return;
    const ro = new ResizeObserver(es => { for (const e of es) setWidth(Math.max(320, e.contentRect.width)); });
    ro.observe(ref.current);
    return () => ro.disconnect();
  }, []);

  const padL = 44, padR = 12, padT = 20, padB = 26;
  const height = 240;
  const innerW = width - padL - padR;
  const innerH = height - padT - padB;
  const slotW = innerW / buckets.length;
  const barW = Math.max(12, Math.min(38, slotW * 0.62));
  const yFor = (v) => padT + innerH - (v / maxTotal) * innerH;

  return (
    <div ref={ref} style={{ width: "100%", position: "relative" }}>
      <svg width={width} height={height} style={{ display: "block" }}>
        {/* Horizontal grid */}
        {[0, 0.25, 0.5, 0.75, 1].map(p => (
          <line key={p} x1={padL} x2={width - padR} y1={padT + p * innerH} y2={padT + p * innerH} stroke="var(--grid)" strokeDasharray="2 4" />
        ))}
        {/* Y axis labels */}
        {[0, 0.5, 1].map(p => (
          <text key={p} x={padL - 6} y={padT + (1 - p) * innerH + 3} textAnchor="end" fontSize="10" fill="var(--text-3)" fontFamily="'Geist Mono', ui-monospace, monospace">
            {showMode === "dollars" ? fmtUSD(maxTotal * p, { compact: true }) : Math.round(maxTotal * p).toLocaleString()}
          </text>
        ))}
        {/* Bars */}
        {buckets.map((b, bi) => {
          const cx = padL + bi * slotW + slotW / 2;
          let stackY = padT + innerH;
          return (
            <g key={bi}>
              {cats.map((cat, ci) => {
                const cellData = (matrix[cat] || {})[bi];
                if (!cellData) return null;
                const v = cellData[showMode] || 0;
                if (v <= 0) return null;
                const h = (v / maxTotal) * innerH;
                stackY -= h;
                const labelFits = h >= 14 && barW >= 24;
                return (
                  <g key={ci}>
                    <rect x={cx - barW/2} y={stackY} width={barW} height={h} fill={colorFor(cat)} rx="2" opacity="0.95">
                      <title>{cat}: {showMode === "dollars" ? fmtUSD(v, {compact:true}) : v.toLocaleString() + " units"}</title>
                    </rect>
                    {labelFits && (
                      <text x={cx} y={stackY + h/2 + 3} textAnchor="middle" fontSize="9.5"
                        fontFamily="'Geist Mono', ui-monospace, monospace" fontWeight="600" fill="#fff"
                        style={{ pointerEvents: "none" }}>
                        {showMode === "dollars" ? fmtUSD(v, { compact: true }) : v.toLocaleString()}
                      </text>
                    )}
                  </g>
                );
              })}
              {/* Total above */}
              {totals[bi] > 0 && (
                <text x={cx} y={stackY - 5} textAnchor="middle" fontSize="10" fill="var(--text)"
                  fontFamily="'Geist Mono', ui-monospace, monospace" fontWeight="600">
                  {showMode === "dollars" ? fmtUSD(totals[bi], {compact: true}) : totals[bi].toLocaleString()}
                </text>
              )}
              {/* X label */}
              <text x={cx} y={height - 8} textAnchor="middle" fontSize="9.5" fill="var(--text-3)">
                {buckets.length > 16 && bi % 2 !== 0 && bi !== buckets.length - 1 ? "" : b.label}
              </text>
            </g>
          );
        })}
      </svg>
    </div>
  );
}

// ─── Inbound Timeline ──────────────────────────────────────────────────
function InboundTimelineCard({ enriched }) {
  const [bucket, setBucket] = useStateO("Week");
  const [groupBy, setGroupBy] = useStateO("ship_method");
  const [showMode, setShowMode] = useStateO("dollars");

  const today = new Date(2026, 4, 15);
  const addDays = (d, n) => { const x = new Date(d); x.setDate(x.getDate() + n); return x; };
  const fmtShort = (d, b) => {
    if (b === "Day")   return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
    if (b === "Week")  return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
    return d.toLocaleDateString("en-US", { month: "short", year: "2-digit" });
  };

  const buckets = (() => {
    if (bucket === "Day") {
      return Array.from({ length: 30 }, (_, i) => ({
        start: addDays(today, i), end: addDays(today, i + 1),
        label: fmtShort(addDays(today, i), "Day"),
      }));
    }
    if (bucket === "Week") {
      return Array.from({ length: 13 }, (_, i) => ({
        start: addDays(today, i * 7), end: addDays(today, (i + 1) * 7),
        label: fmtShort(addDays(today, i * 7), "Week"),
      }));
    }
    return Array.from({ length: 6 }, (_, i) => {
      const start = new Date(today.getFullYear(), today.getMonth() + i, 1);
      const end = new Date(today.getFullYear(), today.getMonth() + i + 1, 1);
      return { start, end, label: fmtShort(start, "Month") };
    });
  })();

  const categoryFor = (po) => {
    if (groupBy === "ship_method") return po.stage === "air" ? "Air" : po.stage === "ocean" ? "Ocean" : po.stage === "port" ? "Port" : po.stage === "supplier" ? "Ground / domestic" : "Draft";
    if (groupBy === "vendor") return po.vendor;
    return po.sku;
  };
  const colorFor = (cat) => {
    const palette = ["var(--accent)", "var(--accent-2)", "var(--warning)", "var(--positive)", "var(--danger)", "#8b5cf6", "#ec4899", "#22d3ee", "#fb923c"];
    const seed = cat.charCodeAt(0) + cat.charCodeAt(cat.length - 1);
    return palette[seed % palette.length];
  };

  const matrix = {};
  const categories = new Set();
  enriched.forEach(po => {
    const idx = buckets.findIndex(b => po.eta >= b.start && po.eta < b.end);
    if (idx < 0) return;
    const cat = categoryFor(po);
    categories.add(cat);
    if (!matrix[cat]) matrix[cat] = {};
    if (!matrix[cat][idx]) matrix[cat][idx] = { units: 0, dollars: 0 };
    matrix[cat][idx].units += po.qty;
    matrix[cat][idx].dollars += po.landed;
  });
  const cats = Array.from(categories);
  const totals = buckets.map((_, bi) => cats.reduce((s, c) => s + ((matrix[c] || {})[bi]?.[showMode] || 0), 0));
  const maxTotal = Math.max(...totals, 1);

  return (
    <Card title="Inbound timeline" subtitle="Visualize what's arriving — bucket by day / week / month"
          action={
            <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                <span style={{ fontSize: 10.5, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5 }}>Bucket</span>
                <SegSmall opts={["Day", "Week", "Month"]} value={bucket} onChange={setBucket} />
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                <span style={{ fontSize: 10.5, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5 }}>Group</span>
                <SegSmall opts={[
                  { value: "ship_method", label: "Method" },
                  { value: "vendor",      label: "Vendor" },
                  { value: "sku",         label: "SKU" },
                ]} value={groupBy} onChange={setGroupBy} />
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                <span style={{ fontSize: 10.5, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5 }}>Show</span>
                <SegSmall opts={[
                  { value: "dollars", label: "$" },
                  { value: "units",   label: "Units" },
                ]} value={showMode} onChange={setShowMode} />
              </div>
            </div>
          } padding={20}>
      <StackedTimeline buckets={buckets} cats={cats} matrix={matrix} totals={totals} maxTotal={maxTotal} colorFor={colorFor} showMode={showMode} />

      <div style={{ display: "flex", gap: 14, flexWrap: "wrap", marginTop: 16, padding: "10px 0", borderTop: "1px solid var(--border)" }}>
        {cats.map(cat => (
          <span key={cat} style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 11.5, color: "var(--text-2)" }}>
            <span style={{ width: 10, height: 10, borderRadius: 2, background: colorFor(cat) }} />
            {cat}
          </span>
        ))}
      </div>

      <div style={{ marginTop: 18, overflowX: "auto" }}>
        <div style={{ fontSize: 10.5, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5, marginBottom: 8 }}>
          Matrix · {showMode === "dollars" ? "Landed $" : "Units"} by {groupBy === "ship_method" ? "shipping method" : groupBy === "vendor" ? "vendor" : "SKU"} × {bucket.toLowerCase()}
        </div>
        <table className="pc-table compact" style={{ minWidth: 800 }}>
          <thead>
            <tr>
              <th style={{ position: "sticky", left: 0, background: "var(--bg-card-solid)", zIndex: 2 }}>{groupBy === "ship_method" ? "Ship method" : groupBy === "vendor" ? "Vendor" : "SKU"}</th>
              {buckets.map((b, bi) => (
                <th key={bi} style={{ textAlign: "right", minWidth: 64, fontSize: 10, whiteSpace: "nowrap" }}>{b.label}</th>
              ))}
              <th style={{ textAlign: "right", fontWeight: 600 }}>Total</th>
            </tr>
          </thead>
          <tbody>
            {cats.map((cat, ci) => {
              const rowTotal = buckets.reduce((s, _, bi) => s + ((matrix[cat] || {})[bi]?.[showMode] || 0), 0);
              return (
                <tr key={ci}>
                  <td style={{ paddingLeft: 14, position: "sticky", left: 0, background: "var(--bg-card-solid)", zIndex: 2 }}>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
                      <span style={{ width: 8, height: 8, borderRadius: 2, background: colorFor(cat) }} />
                      <span style={{ fontWeight: 500 }}>{cat}</span>
                    </span>
                  </td>
                  {buckets.map((_, bi) => {
                    const cell = (matrix[cat] || {})[bi];
                    const v = cell?.[showMode] || 0;
                    const intensity = maxTotal > 0 ? Math.min((v / maxTotal) * 1.4, 1) : 0;
                    return (
                      <td key={bi} style={{
                        textAlign: "right",
                        fontFamily: "'Geist Mono', ui-monospace, monospace",
                        fontSize: 11,
                        fontWeight: v > 0 ? 500 : 400,
                        background: v > 0 ? `color-mix(in srgb, ${colorFor(cat)} ${Math.round(intensity * 22)}%, transparent)` : "transparent",
                        color: v > 0 ? "var(--text)" : "var(--text-4)",
                      }}>
                        {v > 0 ? (showMode === "dollars" ? fmtUSD(v, { compact: true }) : v) : "—"}
                      </td>
                    );
                  })}
                  <td style={{ textAlign: "right", fontFamily: "'Geist Mono', ui-monospace, monospace", fontWeight: 700, color: "var(--text)" }}>
                    {showMode === "dollars" ? fmtUSD(rowTotal, { compact: true }) : rowTotal.toLocaleString()}
                  </td>
                </tr>
              );
            })}
            <tr style={{ borderTop: "2px solid var(--border-strong)" }}>
              <td style={{ paddingLeft: 14, fontWeight: 700, position: "sticky", left: 0, background: "var(--bg-card-solid)", zIndex: 2 }}>Total</td>
              {buckets.map((_, bi) => (
                <td key={bi} style={{ textAlign: "right", fontFamily: "'Geist Mono', ui-monospace, monospace", fontSize: 11, fontWeight: 700, color: "var(--text)" }}>
                  {totals[bi] > 0 ? (showMode === "dollars" ? fmtUSD(totals[bi], { compact: true }) : totals[bi].toLocaleString()) : "—"}
                </td>
              ))}
              <td style={{ textAlign: "right", fontFamily: "'Geist Mono', ui-monospace, monospace", fontWeight: 700, color: "var(--accent)" }}>
                {showMode === "dollars" ? fmtUSD(totals.reduce((s, v) => s + v, 0), { compact: true }) : totals.reduce((s, v) => s + v, 0).toLocaleString()}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </Card>
  );
}

function POStatusPill({ status, stage }) {
  const map = {
    "Delayed":           { bg: "rgba(248,113,113,0.12)", c: "var(--danger)" },
    "In transit":        { bg: "rgba(251,191,36,0.12)",  c: "var(--warning)" },
    "In transit · air":  { bg: "rgba(110,231,183,0.12)", c: "var(--positive)" },
    "At port":           { bg: "rgba(99,102,241,0.12)",  c: "var(--accent-2)" },
    "Approved":          { bg: "rgba(110,231,183,0.10)", c: "var(--positive)" },
    "Pending approval":  { bg: "var(--bg-elev-2)",       c: "var(--text-3)" },
  };
  const s = map[status] || map.Approved;
  return <span className="pc-statpill" style={{ background: s.bg, color: s.c }}>{status}</span>;
}

// ────────────────────────────────────────────────────────────────────────
// SERVICE PRODUCTIVITY (only for service businesses)
// ────────────────────────────────────────────────────────────────────────
function ServicePage({ data, period: globalPeriod, setPeriod: setGlobalPeriod }) {
  const { resources, services } = data;
  const { PeriodComparerEl, compareDeltaSub } = window.usePeriod(globalPeriod, setGlobalPeriod);
  const totalBillable = resources.reduce((s, r) => s + r.billable, 0);
  const totalCapacity = resources.reduce((s, r) => s + r.capacity, 0);
  const avgUtil = (totalBillable / totalCapacity) * 100;
  const benchValue = resources.filter(r => r.util < r.target - 0.1).reduce((s, r) => s + (r.target - r.util) * r.capacity * r.rate, 0);

  return (
    <div className="pc-page">
      {PeriodComparerEl}
      <div className="pc-kpi-grid pc-kpi-grid-4">
        <KPICard label="Avg utilization"   value={avgUtil.toFixed(0) + "%"} delta={1.8} sub={compareDeltaSub || "vs last period"} accent={avgUtil >= 78 ? "var(--positive)" : "var(--warning)"} />
        <KPICard label="Realization"       value="89%" delta={-1.4} hint="Billed / Worked hours" accent="var(--warning)" />
        <KPICard label="Bench cost"        value={fmtUSD(benchValue, { compact: true })} hint="Below-target utilization" accent="var(--danger)" />
        <KPICard label="Revenue per FTE"   value={fmtUSD(720000/resources.length, { compact: true })} delta={4.2} sub={compareDeltaSub || "LTM"} accent="var(--accent)" />
      </div>

      <Card title="Team utilization" subtitle="Last 4 weeks · billable vs capacity"
            action={
              <div style={{ display: "flex", gap: 8 }}>
                <button className="pc-btn-mini ghost"><Icon d={icons.filter} size={12} /> Filter</button>
                <ExportButton rows={resources} filename="Team_utilization" />
              </div>
            } padding={0}>
        <table className="pc-table">
          <thead>
            <tr>
              <th>Resource</th>
              <th>Role</th>
              <th style={{textAlign:"right"}}>Rate</th>
              <th>Utilization</th>
              <th style={{textAlign:"right"}}>vs Target</th>
              <th>Current project</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            {resources.map((r, i) => {
              const gap = r.util - r.target;
              const status = gap >= -0.05 ? "ok" : gap >= -0.15 ? "warn" : "low";
              return (
                <tr key={i} className={status === "low" ? "pc-row-danger" : ""}>
                  <td style={{paddingLeft:14, fontWeight:500}}>
                    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                      <div style={{ width: 26, height: 26, borderRadius: "50%", background: "linear-gradient(135deg, #8b5cf6, #ec4899)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 10, fontWeight: 600 }}>
                        {r.name.split(" ").map(w => w[0]).join("")}
                      </div>
                      {r.name}
                    </div>
                  </td>
                  <td><span className="pc-chip">{r.role}</span></td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{fmtUSD(r.rate)}/hr</td>
                  <td>
                    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                      <Bullet value={r.util * 100} target={r.target * 100} max={100} accent={status === "ok" ? "var(--positive)" : status === "warn" ? "var(--warning)" : "var(--danger)"} />
                      <span style={{ fontSize: 11, fontFamily: "ui-monospace, monospace", color: "var(--text-2)" }}>{(r.util * 100).toFixed(0)}%</span>
                    </div>
                  </td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", color: gap >= 0 ? "var(--positive)" : "var(--danger)"}}>{(gap*100 >= 0 ? "+" : "") + (gap*100).toFixed(0)}pp</td>
                  <td style={{color:"var(--text-2)", fontSize:12}}>{r.project}</td>
                  <td><StatusChip s={status === "ok" ? "ok" : status === "warn" ? "slow" : "stockout"} /></td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </Card>

      <div className="pc-grid-2">
        <Card title="Project profitability" subtitle="Active engagements">
          <table className="pc-table compact">
            <thead><tr><th>Project</th><th style={{textAlign:"right"}}>Booked</th><th style={{textAlign:"right"}}>Burn</th><th>Health</th></tr></thead>
            <tbody>
              {[
                { p: "Halcyon — Phase 2", b: 410000, burn: 0.78, h: "warn" },
                { p: "Atlas — Migration", b: 280000, burn: 0.42, h: "ok" },
                { p: "Ironwood — Build", b: 520000, burn: 0.61, h: "ok" },
                { p: "Quorum — Pilot", b: 92000, burn: 0.31, h: "ok" },
                { p: "Meridian — Discovery", b: 64000, burn: 0.88, h: "warn" },
              ].map((r,i) => (
                <tr key={i}>
                  <td style={{paddingLeft:14, fontWeight:500}}>{r.p}</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{fmtUSD(r.b, {compact:true})}</td>
                  <td><Bullet value={r.burn * 100} target={70} max={100} accent={r.burn < 0.75 ? "var(--positive)" : "var(--warning)"} /></td>
                  <td><StatusChip s={r.h === "warn" ? "slow" : "ok"} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>

        <Card title="Service mix · revenue by line">
          <BarChart
            data={services.slice(0, 5).map((s, i) => ({ label: s.code, value: Math.round((480 - i*40) * s.rate), color: ["var(--accent)","var(--accent-2)","var(--positive)","var(--warning)","#8b5cf6"][i] }))}
            colorFn={(d) => d.color}
            height={200}
          />
        </Card>
      </div>

      {/* Customer cohort analysis */}
      <Card title="Customer cohort analysis" subtitle="Revenue, gross profit per head, and retention by acquisition quarter"
            action={<ExportButton rows={data.serviceCohorts || []} filename="Service_cohorts" />} padding={0}>
        <table className="pc-table">
          <thead>
            <tr>
              <th>Cohort (acq. quarter)</th>
              <th style={{textAlign:"right"}}>Customers</th>
              <th style={{textAlign:"right"}}>LTM revenue</th>
              <th style={{textAlign:"right"}}>Rev / head</th>
              <th style={{textAlign:"right"}}>GP%</th>
              <th style={{textAlign:"right"}}>GP / head</th>
              <th>Retention</th>
              <th>Trend</th>
            </tr>
          </thead>
          <tbody>
            {(data.serviceCohorts || []).map((c, i) => (
              <tr key={i}>
                <td style={{paddingLeft:14, fontWeight: 500}}>{c.cohort}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{c.customers}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{fmtUSD(c.revenue, {compact:true})}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{fmtUSD(c.revenue / c.customers, {compact: true})}</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{c.gpPct.toFixed(1)}%</td>
                <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", fontWeight: 500, color: "var(--positive)"}}>{fmtUSD(c.gpPerHead, {compact: true})}</td>
                <td><Bullet value={c.retention} target={80} max={100} accent={c.retention >= 80 ? "var(--positive)" : c.retention >= 70 ? "var(--warning)" : "var(--danger)"} /></td>
                <td><Sparkline values={Array.from({ length: 12 }, (_, k) => Math.round(c.gpPerHead * (0.85 + Math.sin(i+k) * 0.15)))} width={70} height={22} color="var(--accent)" /></td>
              </tr>
            ))}
          </tbody>
        </table>
      </Card>

      {/* Per-region service analytics */}
      <div className="pc-grid-2">
        <Card title="Service revenue by region" subtitle="Per-head productivity by geography"
              action={<ExportButton rows={data.serviceByRegion || []} filename="Service_by_region" />} padding={0}>
          <table className="pc-table compact">
            <thead>
              <tr>
                <th>Region</th>
                <th style={{textAlign:"right"}}>Revenue</th>
                <th style={{textAlign:"right"}}>Customers</th>
                <th style={{textAlign:"right"}}>FTE</th>
                <th style={{textAlign:"right"}}>Rev / FTE</th>
                <th>GP%</th>
              </tr>
            </thead>
            <tbody>
              {(data.serviceByRegion || []).map((r, i) => (
                <tr key={i}>
                  <td style={{paddingLeft:14, fontWeight: 500}}>{r.region}</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{fmtUSD(r.revenue, {compact:true})}</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{r.customers}</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right"}}>{r.fte}</td>
                  <td style={{fontFamily:"ui-monospace, monospace", textAlign:"right", fontWeight: 500}}>{fmtUSD(r.revenue / r.fte, {compact: true})}</td>
                  <td><Bullet value={r.gpPct} target={55} max={70} accent={r.gpPct >= 55 ? "var(--positive)" : "var(--warning)"} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>

        <Card title="Specialized service KPIs" subtitle="Productivity and engagement metrics">
          <div className="pc-drill-kpi-grid" style={{ gridTemplateColumns: "repeat(2, 1fr)" }}>
            {[
              { l: "Rev / FTE / month",   v: fmtUSD(720000 / resources.length, {compact: true}), d: 4.2 },
              { l: "GP / FTE / month",    v: fmtUSD(720000 * 0.56 / resources.length, {compact: true}), d: 1.8 },
              { l: "Avg engagement size", v: fmtUSD(184000), d: 8.4 },
              { l: "Customer net retention", v: "112%", d: 3.2 },
              { l: "Average bill rate",   v: fmtUSD(280) + "/hr", d: 2.1 },
              { l: "Realization %",       v: "89%",  d: -1.4 },
              { l: "Backlog (weeks)",     v: "11.4", d: 12.8 },
              { l: "Repeat customer %",   v: "84%",  d: 4.1 },
            ].map((k, i) => (
              <div key={i} className="pc-drill-kpi">
                <div className="pc-mk-l">{k.l}</div>
                <div className="pc-mk-v">{k.v}</div>
                <div className="pc-mk-d" style={{ color: k.d >= 0 ? "var(--positive)" : "var(--danger)" }}>
                  {k.d >= 0 ? "▲" : "▼"} {Math.abs(k.d).toFixed(1)}%
                </div>
              </div>
            ))}
          </div>
        </Card>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────────
// EXCEPTIONS INBOX
// ────────────────────────────────────────────────────────────────────────
function ExceptionsPage({ data }) {
  const { exceptions } = data;
  const [sev, setSev] = useStateO("all");
  const [cat, setCat] = useStateO("all");
  const [active, setActive] = useStateO(0);

  const filtered = exceptions.filter(e => (sev === "all" || e.sev === sev) && (cat === "all" || e.category === cat));
  const current = filtered[active] || filtered[0];
  const categories = [...new Set(exceptions.map(e => e.category))];

  return (
    <div className="pc-page" style={{ paddingBottom: 0 }}>
      <div className="pc-kpi-grid pc-kpi-grid-4">
        <KPICard label="Open exceptions" value={exceptions.length} sub={exceptions.filter(e => e.sev === "critical" || e.sev === "high").length + " urgent"} accent="var(--warning)" />
        <KPICard label="Resolved this month" value={12} delta={4} sub="vs. last month" accent="var(--positive)" />
        <KPICard label="Avg time to resolve" value="2.4d" delta={-12.4} sub="vs. last month" accent="var(--positive)" />
        <KPICard label="$ impact (open)"  value={fmtUSD(284000, { compact: true })} hint="Estimated by AI" accent="var(--danger)" />
      </div>

      <div className="pc-exc-shell">
        <div className="pc-exc-list">
          <div className="pc-exc-list-hd">
            <div style={{ display: "flex", gap: 4 }}>
              {["all", "critical", "high", "medium", "low"].map(s => (
                <button key={s} className={"pc-tab " + (sev === s ? "active" : "")} onClick={() => { setSev(s); setActive(0); }}>
                  {s[0].toUpperCase() + s.slice(1)}
                  {s !== "all" && <span style={{ fontSize: 9.5, color: "var(--text-3)", marginLeft: 4 }}>{exceptions.filter(e => e.sev === s).length}</span>}
                </button>
              ))}
            </div>
            <select value={cat} onChange={(e) => { setCat(e.target.value); setActive(0); }} className="pc-mini-select">
              <option value="all">All categories</option>
              {categories.map(c => <option key={c}>{c}</option>)}
            </select>
          </div>
          <div className="pc-exc-rows">
            {filtered.map((ex, i) => (
              <div key={ex.id} className={"pc-exc-listrow " + (i === active ? "active" : "")} onClick={() => setActive(i)}>
                <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }}>
                  <SevPill sev={ex.sev} />
                  <span style={{ fontSize: 10.5, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.4 }}>{ex.category}</span>
                  <span style={{ flex: 1 }} />
                  <span style={{ fontSize: 10.5, color: "var(--text-3)" }}>{ex.ts}</span>
                </div>
                <div style={{ fontSize: 12.5, fontWeight: 500, lineHeight: 1.4, marginBottom: 4 }}>{ex.title}</div>
                <div style={{ fontSize: 11, color: "var(--text-3)" }}>Owner: {ex.owner}</div>
              </div>
            ))}
            {filtered.length === 0 && (
              <div style={{ padding: 40, textAlign: "center", color: "var(--text-3)", fontSize: 12 }}>
                No exceptions match these filters.
              </div>
            )}
          </div>
        </div>

        <div className="pc-exc-detail">
          {current && (
            <>
              <div className="pc-exc-detail-hd">
                <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }}>
                  <SevPill sev={current.sev} />
                  <span style={{ fontSize: 11, color: "var(--text-3)" }}>{current.category} · {current.id} · Detected {current.ts}</span>
                </div>
                <h2 style={{ fontSize: 20, fontWeight: 600, margin: 0, lineHeight: 1.3 }}>{current.title}</h2>
              </div>

              <div className="pc-exc-detail-body">
                <div className="pc-exc-section">
                  <div className="pc-exc-section-label">What happened</div>
                  <div style={{ fontSize: 13, color: "var(--text-2)", lineHeight: 1.6 }}>{current.detail}</div>
                </div>

                <AIInsight>
                  <div style={{ marginBottom: 8 }}>{current.ai}</div>
                </AIInsight>

                <div className="pc-exc-section">
                  <div className="pc-exc-section-label">Drill into the data</div>
                  <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 10 }}>
                    {[
                      { l: "Source records", v: "12 transactions" },
                      { l: "Time window", v: "Apr 18 – May 12" },
                      { l: "$ impact (est.)", v: fmtUSD(48400) },
                    ].map((m, i) => (
                      <div key={i} className="pc-exc-stat">
                        <div style={{ fontSize: 10.5, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: 0.5 }}>{m.l}</div>
                        <div style={{ fontSize: 16, fontFamily: "ui-monospace, monospace", marginTop: 4, fontWeight: 500 }}>{m.v}</div>
                      </div>
                    ))}
                  </div>
                </div>

                <div className="pc-exc-section">
                  <div className="pc-exc-section-label">Suggested actions</div>
                  <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                    {[
                      { t: "Open drill-through · view 12 source transactions", primary: false },
                      { t: "Assign to " + current.owner + " owner", primary: false },
                      { t: "Send to Slack #finance-alerts", primary: false },
                      { t: "Snooze until next cycle", primary: false },
                    ].map((a, i) => (
                      <button key={i} className={"pc-exc-action " + (a.primary ? "primary" : "")}>
                        {a.t} <Icon d={icons.chevron} size={12} />
                      </button>
                    ))}
                  </div>
                </div>

                <div className="pc-exc-section">
                  <div className="pc-exc-section-label">Activity</div>
                  <div style={{ display: "flex", flexDirection: "column", gap: 12, fontSize: 12 }}>
                    <ActivityItem time={current.ts} who="Perdura AI" what="Detected exception" />
                    <ActivityItem time={current.ts} who="Perdura AI" what="Calculated $ impact and proposed action" />
                  </div>
                </div>
              </div>

              <div className="pc-exc-detail-foot">
                <button className="pc-btn ghost">Mark resolved</button>
                <button className="pc-btn primary">Take action</button>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

function ActivityItem({ time, who, what }) {
  return (
    <div style={{ display: "flex", gap: 10, alignItems: "flex-start" }}>
      <div style={{ width: 24, height: 24, borderRadius: 6, background: "radial-gradient(circle at 30% 30%, var(--accent), var(--accent-2))", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
        <Icon d={icons.ai} size={11} stroke="var(--on-accent)" strokeWidth={2.4} />
      </div>
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 12 }}><b>{who}</b> {what}</div>
        <div style={{ fontSize: 10.5, color: "var(--text-3)" }}>{time}</div>
      </div>
    </div>
  );
}

Object.assign(window, { InventoryPage, SupplyPage, ServicePage, ExceptionsPage });
