// Screens 1/3: Dashboard + 3D Viewer (ScreenOnboarding moved to onboarding.jsx)

const { useState: uS1, useEffect: uE1, useMemo: uM1 } = React;

function Form({ fields, form, setForm }) {
  return (
    <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
      {fields.map(([label, key]) => (
        <label key={key} style={{ display: "flex", flexDirection: "column", gap: 4 }}>
          <span className="label">{label}</span>
          <input id="dash-f1" name="dash-f1" value={form[key] || ""} onChange={e => setForm(prev => ({ ...prev, [key]: e.target.value }))}
            style={{ background: "var(--bg-2)", border: "1px solid var(--line)", borderRadius: 4, padding: "6px 8px",
              color: "var(--ink)", fontFamily: "var(--font-mono)", fontSize: 12 }} />
        </label>
      ))}
    </div>
  );
}

function KV({ k, v }) {
  return (
    <div style={{ display: "grid", gridTemplateColumns: "90px 1fr", gap: 8 }}>
      <div className="label">{k}</div>
      <div className="mono" style={{ fontSize: 12, color: "var(--ink-2)" }}>{v}</div>
    </div>
  );
}

function Checklist({ items }) {
  const [done, setDone] = uS1({});
  return (
    <div>
      {items.map((t) => (
        <label key={t} style={{ display: "grid", gridTemplateColumns: "18px 1fr", gap: 8, padding: "6px 0", cursor: "pointer", borderBottom: "1px solid var(--line-soft)" }}>
          <input id="dash-f2" name="dash-f2" type="checkbox" checked={!!done[t]} onChange={e => setDone(prev => ({ ...prev, [t]: e.target.checked }))}
            style={{ accentColor: "var(--accent)" }} />
          <span style={{ textDecoration: done[t] ? "line-through" : "none", color: done[t] ? "var(--ink-4)" : "var(--ink-2)" }}>{t}</span>
        </label>
      ))}
    </div>
  );
}

const DEMO_WORKFLOW_CONFIG_KEY = "forge.demo.workflowConfig";
const DEMO_ACTION_STATE_KEY = "forge.demo.actionState";

function defaultDemoWorkflowConfig() {
  return {
    plan: true,
    build: true,
    line: true,
    traveler: true,
    showAudit: true,
    mode: "ceo",
  };
}

function readDemoWorkflowConfig() {
  if (typeof localStorage === "undefined") return defaultDemoWorkflowConfig();
  try {
    const saved = JSON.parse(localStorage.getItem(DEMO_WORKFLOW_CONFIG_KEY) || "{}");
    return Object.assign(defaultDemoWorkflowConfig(), saved || {});
  } catch (e) {
    return defaultDemoWorkflowConfig();
  }
}

function saveDemoWorkflowConfig(cfg) {
  if (typeof localStorage !== "undefined") localStorage.setItem(DEMO_WORKFLOW_CONFIG_KEY, JSON.stringify(cfg));
}

function readDemoActionState() {
  if (typeof localStorage === "undefined") return {};
  try {
    return JSON.parse(localStorage.getItem(DEMO_ACTION_STATE_KEY) || "{}") || {};
  } catch (e) {
    return {};
  }
}

function saveDemoActionState(state) {
  if (typeof localStorage !== "undefined") localStorage.setItem(DEMO_ACTION_STATE_KEY, JSON.stringify(state));
}

function demoWorkflowStages(tenant) {
  const program = tenant && tenant.program ? tenant.program : {};
  return [
    {
      id: "plan",
      title: "Plan",
      route: "/plan/gantt",
      owner: "Meera S.",
      state: "risk",
      sor: ["Order " + (program.qty || 500) + "u", "Capacity calendar", "Supplier lead times"],
      action: "Replan tranche 1 with NRV cut-in",
      next: "CDMO schedule risk drops from 26% to 14%",
    },
    {
      id: "build",
      title: "Build",
      route: "/forge/ebomtombom",
      owner: "Devansh A.",
      state: "blocked",
      sor: ["EBOM rev B", "MBOM transform", "ECO-0051", "ERP item master"],
      action: "Run EBOM -> MBOM and release routing rev C",
      next: "SAP cost-center drift cleared before WO release",
    },
    {
      id: "line",
      title: "Line",
      route: "/line/readiness",
      owner: "Rohit B.",
      state: "risk",
      sor: ["WO-44219", "Inventory holds", "Tooling readiness", "Supplier ETA"],
      action: "Lock tomorrow's line and expedite SG-400 NRV",
      next: "Station s5/s7 material gaps resolved for next 24h run",
    },
    {
      id: "traveler",
      title: "Traveler",
      route: "/traveler/receiving",
      owner: "Neha G.",
      state: "ready",
      sor: ["Serial TPX-H pool", "Traveler steps", "QG measurements", "NCR log"],
      action: "Push updated traveler and sign QG-23",
      next: "Operator sees the right rev and the ledger gets the receipt",
    },
  ];
}

function demoModelCards(tenant) {
  const boms = (tenant && tenant.boms) || [];
  const costs = (tenant && tenant.cost_cascade) || [];
  const orders = (tenant && tenant.work_orders) || [];
  const meta = {
    "M-27418": ["1.0HP Helios hero run", "ECO-0051 cut-in", "20.07 -> 20.07b blocks ERP T7"],
    "M-26102": ["0.75HP V4 carryover", "ECO-0042 approved", "Completed batch proves tooling reuse"],
    "M-31507": ["5HP pilot scale-up", "WO-44221 pilot", "Machine shop + final test takt pressure"],
  };
  return boms.map(function(b) {
    const cost = costs.find(function(c) { return c.sku === b.sku; }) || {};
    const wo = orders.find(function(w) { return w.sku === b.sku; }) || {};
    const m = meta[b.sku] || [b.sku, "Configured model", "No exception"];
    return {
      sku: b.sku,
      label: m[0],
      state: wo.status || "engineering",
      signal: m[1],
      exception: m[2],
      lines: (b.lines || []).length,
      cost: cost.total_inr || 0,
      wo: wo.id || "no WO",
      qty: wo.qty || 0,
    };
  });
}

function DemoConfigSwitch({ id, label, cfg, setCfg }) {
  return (
    <label style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 12, color: "var(--ink-2)", cursor: "pointer" }}>
      <input id="dash-f3" name="dash-f3"
        type="checkbox"
        checked={!!cfg[id]}
        onChange={function(e) {
          const next = Object.assign({}, cfg, { [id]: e.target.checked });
          setCfg(next);
          saveDemoWorkflowConfig(next);
        }}
        style={{ accentColor: "var(--accent)" }}
      />
      <span>{label}</span>
    </label>
  );
}

function ExecutivePulseCard({ label, value, tone, sor, action, route }) {
  return (
    <button
      onClick={function() { if (typeof navigate === "function") navigate(route); }}
      style={{
        textAlign: "left",
        padding: 12,
        border: "1px solid var(--line-soft)",
        background: "var(--bg-1)",
        borderRadius: 6,
        cursor: "pointer",
        minWidth: 0,
      }}
    >
      <div className="label">{label}</div>
      <div className="mono tnum" style={{ fontSize: 22, color: tone || "var(--ink)", marginTop: 3 }}>{value}</div>
      <div className="muted mono" style={{ fontSize: 12, marginTop: 8 }}>SoR · {sor}</div>
      <div style={{ fontSize: 12, color: "var(--ink-2)", marginTop: 3 }}>{action}</div>
    </button>
  );
}

function StageCard({ stage, done, onStrike }) {
  const tone = stage.state === "blocked" ? "err" : stage.state === "risk" ? "warn" : "ok";
  return (
    <div style={{ padding: 12, border: "1px solid var(--line-soft)", borderRadius: 6, background: "var(--bg-1)", minWidth: 0 }}>
      <div style={{ display: "flex", justifyContent: "space-between", gap: 8, alignItems: "center" }}>
        <div>
          <div className="mono" style={{ fontSize: 12, color: "var(--accent)" }}>{stage.title.toUpperCase()}://</div>
          <div style={{ fontSize: 15, color: "var(--ink)", marginTop: 2 }}>{stage.action}</div>
        </div>
        <Pill tone={done ? "ok" : tone}>{done ? "signed" : stage.state}</Pill>
      </div>
      <div className="hr"/>
      <div className="label">System of record</div>
      <div style={{ display: "flex", gap: 5, flexWrap: "wrap", marginTop: 6 }}>
        {stage.sor.map(function(x) { return <Tag key={x}>{x}</Tag>; })}
      </div>
      <div className="label" style={{ marginTop: 10 }}>System of action result</div>
      <div className="muted" style={{ fontSize: 12, marginTop: 3 }}>{stage.next}</div>
      <div style={{ display: "flex", gap: 6, marginTop: 12 }}>
        <Btn size="sm" icon="Eye" onClick={function() { if (typeof navigate === "function") navigate(stage.route); }}>Open lane</Btn>
        <Btn size="sm" icon="Check" variant={done ? "ghost" : "primary"} onClick={function() { onStrike(stage); }}>{done ? "Receipt saved" : "Strike"}</Btn>
      </div>
    </div>
  );
}

function ScreenExecutiveCockpit({ tenant }) {
  const program = tenant && tenant.program ? tenant.program : {};
  const [cfg, setCfg] = uS1(readDemoWorkflowConfig);
  const [actions, setActions] = uS1(readDemoActionState);
  const [selectedSku, setSelectedSku] = uS1(function() {
    return (typeof localStorage !== "undefined" && localStorage.getItem("forge.variantSku")) || "M-27418";
  });

  const stages = demoWorkflowStages(tenant).filter(function(s) { return cfg[s.id]; });
  const modelCards = demoModelCards(tenant);
  const selectedModel = modelCards.find(function(m) { return m.sku === selectedSku; }) || modelCards[0];
  const completedCount = stages.filter(function(s) { return actions[s.id]; }).length;

  const strike = function(stage) {
    const next = Object.assign({}, actions, {
      [stage.id]: {
        at: new Date().toISOString(),
        action: stage.action,
        actor: cfg.mode === "cto" ? "CTO console" : "CEO console",
        receipt: "STRIKE-" + stage.id.toUpperCase() + "-" + String(Date.now()).slice(-5),
      },
    });
    setActions(next);
    saveDemoActionState(next);
  };

  const reset = function() {
    const base = defaultDemoWorkflowConfig();
    setCfg(base);
    setActions({});
    setSelectedSku("M-27418");
    saveDemoWorkflowConfig(base);
    saveDemoActionState({});
    if (typeof localStorage !== "undefined") localStorage.setItem("forge.variantSku", "M-27418");
    if (typeof window !== "undefined") window.dispatchEvent(new CustomEvent("forge:variant-change", { detail: { sku: "M-27418" } }));
  };

  const pickModel = function(sku) {
    setSelectedSku(sku);
    if (typeof localStorage !== "undefined") localStorage.setItem("forge.variantSku", sku);
    if (typeof window !== "undefined") window.dispatchEvent(new CustomEvent("forge:variant-change", { detail: { sku: sku } }));
  };

  const exceptions = [
    ["P0", "SAP item master drift", "20.07b lacks cost-center on rev B", "/build/erp"],
    ["P1", "ECO not cut into traveler", "Old NRV traveler still visible before TPX-H-0101", "/traveler/receiving"],
    ["P1", "Supplier cert gate", "S.G.-400 cert needed before receiving release", "/line/readiness"],
    ["P2", "Variant takt pressure", "M-31507 final test needs extra pressure window", "/build/mbom"],
  ];

  return (
    <div style={{ padding: 14, display: "grid", gridTemplateRows: "auto auto minmax(260px, 1fr) auto", gap: 14, minHeight: 0, height: "100%" }}>
      <Panel title="CEO/CTO cockpit · system of record to system of action" right={
        <>
          <button onClick={function() {
            const next = Object.assign({}, cfg, { mode: cfg.mode === "ceo" ? "cto" : "ceo" });
            setCfg(next); saveDemoWorkflowConfig(next);
          }} className="btn sm">{cfg.mode.toUpperCase()}</button>
          <Btn size="sm" icon="Refresh" onClick={reset}>Reset demo</Btn>
        </>
      }>
        <div style={{ padding: 14, display: "grid", gridTemplateColumns: "minmax(260px, .9fr) minmax(420px, 1.6fr) minmax(260px, .9fr)", gap: 14 }}>
          <div>
            <div className="label">Program spine</div>
            <div className="serif" style={{ fontSize: 26, lineHeight: 1.1, marginTop: 4 }}>{program.name || "M-27418 program"}</div>
            <div className="muted" style={{ fontSize: 12, marginTop: 6 }}>{program.customer || "Helios AgriFlow"} · {program.qty || 500} units · {program.phase || "Industrialize"}</div>
            <div style={{ marginTop: 12, display: "grid", gap: 7 }}>
              <KV k="SoR anchor" v="Quote, EBOM, SAP item master, MES work order, traveler, ledger" />
              <KV k="Next gate" v={(program.nextMilestone || "Pilot lot dispatch") + " · " + (program.nextDate || "2026-05-20")} />
              <KV k="Signed actions" v={completedCount + " / " + stages.length + " demo strikes"} />
            </div>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(5, minmax(0, 1fr))", gap: 8 }}>
            <ExecutivePulseCard label="Delivery confidence" value="74%" tone="var(--warn)" sor="Plan + WO" action="Replan tranche 1" route="/plan/gantt" />
            <ExecutivePulseCard label="Margin at risk" value={(window.forgeI18n && window.forgeI18n.formatMoneyMinor("95000000", "INR")) || "₹9,50,000"} tone="var(--err)" sor="SAP cost + ECO" action="Approve NRV delta" route="/build/eco" />
            <ExecutivePulseCard label="Line readiness" value="86%" tone="var(--ok)" sor="MES + inventory" action="Lock line" route="/line/readiness" />
            <ExecutivePulseCard label="Quality escapes" value="5" tone="var(--err)" sor="RMA + ledger" action="Close ECO loop" route="/forge/field-issues" />
            <ExecutivePulseCard label="SoR drift" value="3" tone="var(--warn)" sor="PLM/SAP/MES" action="Run reconcile" route="/build/connectors" />
          </div>
          <div>
            <div className="label">Workflow config</div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginTop: 8 }}>
              <DemoConfigSwitch id="plan" label="Plan lane" cfg={cfg} setCfg={setCfg} />
              <DemoConfigSwitch id="build" label="Build lane" cfg={cfg} setCfg={setCfg} />
              <DemoConfigSwitch id="line" label="Line lane" cfg={cfg} setCfg={setCfg} />
              <DemoConfigSwitch id="traveler" label="Traveler lane" cfg={cfg} setCfg={setCfg} />
              <DemoConfigSwitch id="showAudit" label="Receipts" cfg={cfg} setCfg={setCfg} />
            </div>
            <div className="hr"/>
            <div className="muted" style={{ fontSize: 12 }}>Everything here is client-side and persisted in localStorage for the demo. The buttons still navigate to the real route surfaces.</div>
          </div>
        </div>
      </Panel>

      <Panel title="Chronological flow · Plan -> Build -> Line -> Traveler">
        <div style={{ padding: 12, display: "grid", gridTemplateColumns: `repeat(${Math.max(stages.length, 1)}, minmax(220px, 1fr))`, gap: 10 }}>
          {stages.map(function(stage) {
            return <StageCard key={stage.id} stage={stage} done={!!actions[stage.id]} onStrike={strike} />;
          })}
        </div>
      </Panel>

      <div style={{ display: "grid", gridTemplateColumns: "1.05fr 1fr .95fr", gap: 14, minHeight: 0 }}>
        <Panel title="Model / variant control" right={<Tag>{selectedModel ? selectedModel.sku : "—"}</Tag>}>
          <div style={{ padding: 10, display: "grid", gap: 8 }}>
            {modelCards.map(function(m) {
              const active = m.sku === selectedSku;
              return (
                <button key={m.sku} onClick={function() { pickModel(m.sku); }}
                  style={{ textAlign: "left", padding: 10, borderRadius: 6, border: "1px solid " + (active ? "var(--accent)" : "var(--line-soft)"), background: active ? "var(--bg-2)" : "var(--bg-1)", cursor: "pointer" }}>
                  <div style={{ display: "flex", justifyContent: "space-between", gap: 8 }}>
                    <div className="mono" style={{ color: active ? "var(--accent)" : "var(--ink)" }}>{m.sku}</div>
                    <Pill tone={m.state === "in-progress" ? "warn" : m.state === "pilot" ? "info" : "ok"}>{m.state}</Pill>
                  </div>
                  <div style={{ fontSize: 13, color: "var(--ink)", marginTop: 3 }}>{m.label}</div>
                  <div className="muted mono" style={{ fontSize: 12, marginTop: 3 }}>{m.lines} EBOM lines · {m.wo} · {m.qty || "—"}u · {(window.forgeI18n && window.forgeI18n.formatMoneyMinor(String((m.cost || 0) * 100), "INR")) || ("₹" + (m.cost || 0).toLocaleString())}/u</div>
                  <div style={{ fontSize: 12, color: "var(--warn)", marginTop: 5 }}>{m.exception}</div>
                </button>
              );
            })}
            <div style={{ display: "flex", gap: 6 }}>
              <Btn size="sm" icon="Tree" onClick={function() { if (typeof navigate === "function") navigate("/forge/ebom"); }}>Open EBOM</Btn>
              <Btn size="sm" icon="Factory" onClick={function() { if (typeof navigate === "function") navigate("/build/mbom"); }}>Open MBOM</Btn>
            </div>
          </div>
        </Panel>

        <Panel title="Exception board · SoR mismatches">
          <table className="dtable">
            <thead><tr><th>Pri</th><th>Mismatch</th><th>Impact</th><th></th></tr></thead>
            <tbody>
              {exceptions.map(function(e) {
                return (
                  <tr key={e[1]}>
                    <td><Pill tone={e[0] === "P0" ? "err" : e[0] === "P1" ? "warn" : "info"}>{e[0]}</Pill></td>
                    <td style={{ color: "var(--ink)" }}>{e[1]}</td>
                    <td>{e[2]}</td>
                    <td><button className="btn sm" onClick={function() { if (typeof navigate === "function") navigate(e[3]); }}>Open</button></td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </Panel>

        <Panel title="Action receipts">
          <div style={{ padding: 10, display: "grid", gap: 8 }}>
            {cfg.showAudit && Object.keys(actions).length ? Object.keys(actions).map(function(id) {
              const a = actions[id];
              return (
                <div key={id} style={{ border: "1px solid var(--line-soft)", borderRadius: 6, padding: 9 }}>
                  <div style={{ display: "flex", justifyContent: "space-between", gap: 8 }}>
                    <span className="mono" style={{ color: "var(--ok)", fontSize: 12 }}>{a.receipt}</span>
                    <Pill tone="ok">signed</Pill>
                  </div>
                  <div style={{ fontSize: 12, color: "var(--ink)", marginTop: 4 }}>{a.action}</div>
                  {/* react-doctor-disable-next-line */}
                  <div suppressHydrationWarning className="muted mono" style={{ fontSize: 12, marginTop: 3 }}>{a.actor} · {(window.forgeI18n && window.forgeI18n.formatDateTime(a.at)) || new Date(a.at).toLocaleString()}</div>
                </div>
              );
            }) : (
              <div className="muted" style={{ padding: 14, fontSize: 12 }}>No strikes yet. Use the action buttons in the chronological flow to create signed demo receipts.</div>
            )}
            <Btn size="sm" icon="Check" onClick={function() { if (typeof navigate === "function") navigate("/auditor/ledger"); }}>Open auditor ledger</Btn>
          </div>
        </Panel>
      </div>
    </div>
  );
}

// ---------- DASHBOARD ----------
// Derive the 6 KPI cells from primary fixtures (NEVER hand-typed).
// Source rules (week 1):
//   Active SKUs       = distinct boms.sku
//   Open RFQs         = ledger rfq_received minus ledger po_received (floored at 0)
//   WOs scheduled     = work_orders in {scheduled, released, in-progress, pilot}
//   Open ECOs         = eco where status != 'applied'
//   Audits due 30d    = vendor_audit_started events with no later vendor_audit_completed
//   Line-readiness %  = avg(per-station avg) across in-progress work_orders
function deriveTritanKpis(tenant) {
  const boms = (tenant && tenant.boms) || [];
  const ledger = (tenant && tenant.ledger) || [];
  const workOrders = (tenant && tenant.work_orders) || [];
  const eco = (tenant && tenant.eco) || [];

  // Active SKUs — distinct sku from boms (fixture uses `sku`, not `parent_sku`).
  const activeSkus = new Set(boms.map(function (b) { return b.sku; })).size;

  // Open RFQs — rfq_received events without a corresponding po_received.
  // The fixture's ledger doesn't link rfq_id → po_id, so we approximate:
  // openRFQs = max(0, count(rfq_received) - count(po_received)).
  const rfqCount = ledger.filter(function (e) { return e.type === "rfq_received"; }).length;
  const poCount  = ledger.filter(function (e) { return e.type === "po_received"; }).length;
  const openRfqs = Math.max(0, rfqCount - poCount);

  // WOs scheduled — anything actively in the pipeline.
  const woStatuses = ["scheduled", "released", "in-progress", "pilot"];
  const wosScheduled = workOrders.filter(function (w) { return woStatuses.indexOf(w.status) !== -1; }).length;

  // Open ECOs — not yet applied.
  const openEcos = eco.filter(function (e) { return e.status !== "applied"; }).length;

  // Audits due 30d — vendor_audit_started without a later vendor_audit_completed.
  // Approximation: count(vendor_audit_started) - count(vendor_audit_completed), floored at 0.
  const startCt = ledger.filter(function (e) { return e.type === "vendor_audit_started"; }).length;
  const doneCt  = ledger.filter(function (e) { return e.type === "vendor_audit_completed"; }).length;
  const auditsDue = Math.max(0, startCt - doneCt);

  // Line-readiness % — for each in-progress WO, average station_progress values;
  // then average across WOs. station_progress is an object {s1..s7}.
  const inProgress = workOrders.filter(function (w) { return w.status === "in-progress"; });
  let lineReadiness = 0;
  if (inProgress.length > 0) {
    const perWo = inProgress.map(function (w) {
      const sp = w.station_progress || {};
      const vals = Object.keys(sp).map(function (k) { return Number(sp[k]) || 0; });
      return vals.length ? vals.reduce(function (a, b) { return a + b; }, 0) / vals.length : 0;
    });
    lineReadiness = perWo.reduce(function (a, b) { return a + b; }, 0) / perWo.length;
  }

  return [
    { k: "Active SKUs",      v: String(activeSkus),                  d: "from BOMs",         trend: "flat" },
    { k: "Open RFQs",        v: String(openRfqs),                    d: "awaiting PO",       trend: openRfqs > 0 ? "up" : "flat" },
    { k: "WOs scheduled",    v: String(wosScheduled),                d: "in pipeline",       trend: "flat" },
    { k: "Open ECOs",        v: String(openEcos),                    d: openEcos ? "needs approval" : "—", trend: "flat" },
    { k: "Audits due 30d",   v: String(auditsDue),                   d: "follow-ups",        trend: auditsDue > 0 ? "down" : "flat" },
    { k: "Line-readiness %", v: Math.round(lineReadiness * 100) + "%", d: inProgress.length + " in-progress", trend: "up" },
  ];
}

function ScreenDashboard() {
  const tenant = useActiveTenant();
  const program = (tenant && tenant.program) || PROGRAM;
  const kpis    = (tenant && tenant.kpis && tenant.kpis.length) ? tenant.kpis : KPIS;
  const isStub  = tenant && tenant.depth && tenant.depth !== "deep";
  const isTritan = tenant && tenant.tenant && tenant.tenant.id === "tritan";

  if (isTritan) {
    // ── Tritan dashboard · derived KPIs + ProgramCard + ActivityStream ──
    // Refactored from the legacy ScreenExecutiveCockpit. Every number is computed
    // from PUMP_TENANT.{boms, ledger, work_orders, eco}; nothing hand-typed.
    const derivedKpis = deriveTritanKpis(tenant);
    const PC = window.ProgramCard;
    const AS = window.ActivityStream;

    return (
      <div style={{ padding: 14, display: "grid", gridTemplateColumns: "1.4fr 1fr", gridTemplateRows: "auto auto 1fr", gap: 14, minHeight: 0, height: "100%", overflowY: "auto" }}>
        {/* Program card · row 1 col 1 */}
        <div style={{ gridColumn: "1 / 2", gridRow: "1 / 2" }}>
          {PC ? <PC tenant={tenant} /> : (
            <Panel title="Program · M-27418">
              <div className="muted" style={{ padding: 14, fontSize: 12 }}>ProgramCard component not loaded.</div>
            </Panel>
          )}
        </div>

        {/* Activity stream · spans rows 1-3 col 2 */}
        <div style={{ gridColumn: "2 / 3", gridRow: "1 / 4", minHeight: 0 }}>
          {AS ? <AS title="Activity · Helios timeline" /> : (
            <Panel title="Activity · Helios timeline">
              <div className="muted" style={{ padding: 14, fontSize: 12 }}>ActivityStream component not loaded.</div>
            </Panel>
          )}
        </div>

        {/* KPI strip · row 2 col 1 — all derived */}
        <div style={{ gridColumn: "1 / 2", gridRow: "2 / 3" }}>
          <Panel title="KPIs · derived from primary data">
            <div style={{ display: "grid", gridTemplateColumns: "repeat(" + derivedKpis.length + ", 1fr)" }}>
              {derivedKpis.map(function (k) {
                return <StatPill key={k.k} label={k.k} value={k.v} delta={k.d} trend={k.trend} />;
              })}
            </div>
          </Panel>
        </div>

        {/* Quick lanes · row 3 col 1 */}
        <div style={{ gridColumn: "1 / 2", gridRow: "3 / 4", minHeight: 0 }}>
          <Panel title="Quick lanes">
            <div style={{ padding: 14, display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 10 }}>
              {[
                ["Plan",     "/plan/gantt",         "Calendar"],
                ["Build",    "/build/mbom",         "Factory"],
                ["Line",     "/line/readiness",     "Factory"],
                ["Traveler", "/traveler/receiving", "Wrench"],
              ].map(function (row) {
                return (
                  <button
                    key={row[0]}
                    onClick={function () { if (typeof navigate === "function") navigate(row[1]); }}
                    style={{ padding: 14, borderRadius: 6, border: "1px solid var(--line-soft)", background: "var(--bg-1)", cursor: "pointer", textAlign: "left" }}
                  >
                    <div className="mono" style={{ fontSize: 12 }}>
                      <span style={{ color: "var(--ink)", fontWeight: 600 }}>{row[0].toUpperCase()}</span>
                      <span style={{ color: "var(--accent)" }}>://</span>
                    </div>
                    <div style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 4 }}>Open lane →</div>
                  </button>
                );
              })}
            </div>
          </Panel>
        </div>
      </div>
    );
  }

  // Project ERP queue rows from the active tenant when available, else fall back to data.jsx ERP_QUEUE.
  const erpRows = isTritan && tenant.parts && tenant.parts.length
    ? tenant.parts.slice(0, 6).map(function(p, i) {
        const states = ["synced","awaiting-sync","validating","blocked","synced","synced"];
        const drifts = ["—","fields mismatched: UOM, lot-size","—","missing cost-center on rev B","—","—"];
        return {
          pn: p.num, name: p.name, rev: "B",
          item: "ITM-" + String(40 + i * 7).padStart(4, "0"),
          state: states[i % states.length],
          drift: drifts[i % drifts.length],
        };
      })
    : ERP_QUEUE;

  const burnRev = (program && program.revision) ? program.revision : "C";
  const milestones = isTritan
    ? [
        ["RFQ received",       "complete", "2026-02-14"],
        ["Vendor audit · Helios","complete","2026-04-10"],
        ["Pilot lot · 10 units","current", "2026-05-05"],
        ["Tranche 1 dispatch", "planned",  "2026-05-20"],
        ["Order close (500u)", "planned",  "2026-06-24"],
      ]
    : [
        ["DR-2", "complete", "2026-02-10"],
        ["Freeze · Rotor geom", "complete", "2026-03-22"],
        ["DR-3 · CDR", "current", "2026-05-14"],
        ["FAT-0 · ST-50", "planned", "2026-07-02"],
        ["SOP", "planned", "2026-09-18"],
      ];

  const [range, setRange] = uS1("14d");
  const loadSpark  = [42,48,47,55,52,60,58,63,69,64,71,76,78,83];
  const burnSpark  = [10,14,19,27,31,36,41,46,51,57,62,70,78,84];
  const convSpark  = [1,0.4,0.3,0.12,0.08,0.05,0.04,0.03,0.02,0.019,0.017,0.015,0.013,0.011];
  return (
    <div style={{ padding: 14, display: "grid", gridTemplateColumns: "1.5fr 1fr", gridTemplateRows: "auto 1fr 1fr", gap: 14, minHeight: 0, height: "100%" }}>
      <Panel className="grid-bg" title={`Program · ${program?.code ?? "—"}`} right={
        <>
          {["7d","14d","30d"].map(r => <Btn key={r} size="sm" variant={r===range?"primary":"ghost"} onClick={()=>setRange(r)}>{r}</Btn>)}
          <Btn size="sm" icon="Plus" onClick={() => window.forgeToast && window.forgeToast("New workpkg queued — wired in v2")}>New workpkg</Btn>
        </>}>
        <div style={{ padding: 14, display: "flex", gap: 16 }}>
          <div style={{ flex: 1 }}>
            <div className="label">Program</div>
            <div className="serif" style={{ fontSize: 30, lineHeight: 1.1 }}>{program?.name ?? "—"}</div>
            <div className="muted" style={{ marginTop: 4 }}>{program?.customer ?? "—"} · Phase · <span style={{ color: "var(--ink)" }}>{program?.phase ?? "—"}</span></div>
            <div style={{ display: "flex", gap: 8, marginTop: 10, alignItems: "center" }}>
              <Pill tone="accent">Rev {program?.revision ?? "—"}</Pill>
              {program?.nextMilestone && <Pill tone="info">{program.nextMilestone}</Pill>}
              {program?.nextDate && <span className="mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>due {program.nextDate}</span>}
            </div>
            <div style={{ marginTop: 14 }}>
              <div className="label">Program progress</div>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 4 }}>
                <Progress value={program?.progress ?? 0} />
                <span className="mono tnum" style={{ fontSize: 12 }}>{Math.round((program?.progress ?? 0)*100)}%</span>
              </div>
            </div>
          </div>
          <div style={{ width: 260, borderLeft: "1px solid var(--line-soft)", paddingLeft: 14 }}>
            <div className="label">Milestones</div>
            {milestones.map(([m, s, d]) =>
              <div key={m} style={{ display: "grid", gridTemplateColumns: "12px 1fr auto", gap: 8, padding: "6px 0", alignItems: "center" }}>
                <span style={{ width: 8, height: 8, borderRadius: 8,
                  background: s==="complete"?"var(--ok)":s==="current"?"var(--accent)":"var(--line-strong)" }}/>
                <div style={{ fontSize: 12, color: s==="planned"?"var(--ink-3)":"var(--ink)" }}>{m}</div>
                <div className="mono tnum" style={{ fontSize: 12, color: "var(--ink-3)" }}>{d}</div>
              </div>
            )}
          </div>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: `repeat(${Math.max(kpis.length, 1)}, 1fr)`, borderTop: "1px solid var(--line-soft)" }}>
          {kpis.map(k => <StatPill key={k.k} label={k.k} value={k.v} delta={k.d} trend={k.trend} />)}
        </div>
      </Panel>

      {/* Wave 3C item 26: replace inline fake events with the live ActivityStream
          (SSE-backed, tenant-aware via window.forgeApi.subscribeEvents). */}
      {(function() {
        const AS = (typeof window !== "undefined") ? window.ActivityStream : null;
        if (AS) return <AS title="Stream · Activity" />;
        return (
          <Panel title="Stream · Activity">
            <div className="muted" style={{ padding: 14, fontSize: 12 }}>ActivityStream component not loaded.</div>
          </Panel>
        );
      })()}

      <Panel title="Load · compute" right={<Tag>last {range}</Tag>}>
        <div style={{ padding: 12 }}>
          <Spark data={loadSpark} height={44} />
          <div style={{ display: "flex", justifyContent: "space-between", marginTop: 8 }}>
            <div><div className="label">Avg core-hrs/day</div><div className="mono tnum" style={{ fontSize: 18 }}>{isTritan ? "192" : "2,864"}</div></div>
            <div><div className="label">Peak cores</div><div className="mono tnum" style={{ fontSize: 18 }}>{isTritan ? "76" : "1,152"}</div></div>
            <div><div className="label">License util.</div><div className="mono tnum" style={{ fontSize: 18 }}>{isTritan ? "88%" : "72%"}</div></div>
          </div>
          {isTritan && <div className="muted" style={{ fontSize: 12, marginTop: 6 }}>physical test gates · light compute load</div>}
        </div>
      </Panel>

      <Panel title="Engineering burndown" right={<Tag>rev {isTritan ? "B" : burnRev}</Tag>}>
        <div style={{ padding: 12 }}>
          <Spark data={burnSpark} height={44} stroke="var(--accent)" />
          <div style={{ display: "flex", justifyContent: "space-between", marginTop: 8 }}>
            <div><div className="label">Remaining work</div><div className="mono tnum" style={{ fontSize: 18 }}>{isTritan ? "32 d" : "138 d"}</div></div>
            <div><div className="label">Slope</div><div className="mono tnum" style={{ fontSize: 18 }}>{isTritan ? "−8.2 d/wk" : "−5.2 d/wk"}</div></div>
            <div><div className="label">Forecast</div><div className="mono tnum" style={{ fontSize: 18 }}>{isTritan ? "May 18" : "May 09"}</div></div>
          </div>
        </div>
      </Panel>

      <Panel title="ERP release queue · at a glance">
        <table className="dtable">
          <thead><tr><th>Part</th><th>Name</th><th>Rev</th><th>Item</th><th>State</th><th>Drift</th></tr></thead>
          <tbody>
            {erpRows.slice(0,6).map(r => (
              <tr key={r.pn}>
                <td>{r.pn}</td>
                <td style={{ color: "var(--ink)" }}>{r.name}</td>
                <td>{r.rev}</td>
                <td>{r.item}</td>
                <td><Pill tone={r.state==="synced"?"ok":r.state==="blocked"?"err":r.state==="validating"?"info":"warn"}>{r.state}</Pill></td>
                <td style={{ color: r.drift === "—" ? "var(--ink-4)" : "var(--warn)" }}>{r.drift}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </Panel>

      <Panel title="Sim queue" right={<Btn size="sm" icon="Play" onClick={() => window.forgeToast && window.forgeToast("Sim job submitted — wired in v2")}>Submit job</Btn>}>
        {isTritan ? (
          <div style={{ padding: 24, textAlign: "center" }}>
            <div className="serif" style={{ fontSize: 18, lineHeight: 1.2, marginBottom: 8 }}>No simulation studies</div>
            <div className="muted" style={{ fontSize: 12, marginBottom: 14 }}>Tritan validates via 30-point CTQ physical gates; see /build/gates</div>
            <Btn size="sm" variant="primary" icon="Check" onClick={function() { if (typeof navigate === "function") navigate("/build/gates"); else window.location.hash = "/build/gates"; }}>See Quality Gates</Btn>
          </div>
        ) : (
          <table className="dtable">
            <thead><tr><th>ID</th><th>Study</th><th>Domain</th><th>Cores</th><th>ETA</th><th>State</th></tr></thead>
            <tbody>
              {STUDIES.slice(0, 6).map(s => (
                <tr key={s.id}>
                  <td>{s.id}</td>
                  <td style={{ color: "var(--ink)" }}>{s.name}</td>
                  <td style={{ color: "var(--cool)" }}>{s.domain}</td>
                  <td className="tnum">{s.cores}</td>
                  <td className="tnum">{s.eta}</td>
                  <td><Pill tone={s.status==="complete"?"ok":s.status==="running"?"info":s.status==="queued"?"warn":"err"}>{s.status}</Pill></td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </Panel>
    </div>
  );
}

// ---------- 3D VIEWER ----------
function ScreenViewer({ selectedPn, setSelectedPn }) {
  const tenant = useActiveTenant();
  const isTritan = tenant && tenant.tenant && tenant.tenant.id === "tritan";
  const fallbackPn = (tenant && tenant.program && tenant.program.code) ? tenant.program.code : "HTU-220.00.00";
  // Inspector & where-used sample rows — tenant-conditional so Tritan shows pump parts.
  const inspectorRows = isTritan
    ? [
        ["Part", (tenant.parts && tenant.parts[10] && tenant.parts[10].num) || "M-27418.10.02"],
        ["Name", (tenant.parts && tenant.parts[10] && tenant.parts[10].name) || "Rotor Shaft SS410"],
        ["Rev", "B · released"], ["Source", "MAKE"],
        ["Material", "SS 410 / EN 1.4006"], ["Mass", "0.84 kg"],
        ["Volume", "0.00011 m³"], ["COG (x,y,z)", "0.00, 0.00, 0.12"],
        ["Drawing", "DWG-RS-410-B"], ["CAD owner", "Devansh A."],
        ["Lifecycle", "Released"], ["Classification", "Rotating part · primary"],
      ]
    : [
        ["Part", "HTU-220.10.02"], ["Name", "Blade · Airfoil A"],
        ["Rev", "C · in-work"], ["Source", "MAKE"],
        ["Material", "CFRP layup L-7"], ["Mass", "487.2 kg"],
        ["Volume", "0.311 m³"], ["COG (x,y,z)", "0.12, 0.00, 1.84"],
        ["Drawing", "DWG-10.02-C"], ["CAD owner", "J. Park"],
        ["Lifecycle", "Detail Design"], ["Classification", "Primary structure"],
      ];
  const whereUsedRows = isTritan
    ? [
        ["M-27418.10.00 Motor Sub-assembly", "1", "M-27418"],
        ["M-27418.00.00 Pumpset", "1", "M-27418"],
        ["M-26102.10.00 Motor (predecessor)", "1", "M-26102"],
      ]
    : [
        ["HTU-220.10.00 Rotor Assembly", "3", "HTU-220"],
        ["HTU-220.00.00 Turbine Unit", "3", "HTU-220"],
        ["HTU-180.10.00 Rotor (legacy)", "3", "HTU-180"],
      ];
  const [mode, setMode] = uS1("iso");
  const [visLayers, setVisLayers] = uS1({ geom: true, mesh: false, bcs: false, annot: true });

  return (
    <div style={{ padding: 14, display: "grid", gridTemplateColumns: "1fr 320px", gap: 14, minHeight: 0, height: "100%" }}>
      <Panel title={`3D Part Studio · ${selectedPn || fallbackPn}`} right={
        <>
          {["iso","front","top","side","section"].map(m => <Btn key={m} size="sm" variant={m===mode?"primary":"ghost"} onClick={()=>setMode(m)}>{m}</Btn>)}
          <Btn size="sm" icon="Gear" onClick={() => window.forgeToast && window.forgeToast("Render options queued — wired in v2")}>render</Btn>
        </>}>
        <div style={{ position: "relative", height: "100%" }}>
          <ViewerCanvas mode={mode} visLayers={visLayers} isTritan={isTritan} />
          <ViewerOverlay mode={mode} />
          <div style={{ position: "absolute", bottom: 10, left: 10, display: "flex", gap: 6 }}>
            {Object.entries(visLayers).map(([k, v]) => {
              const _visLayerBtnStyle = { padding: "3px 8px", border: "1px solid var(--line)", borderRadius: 4,
                background: v ? "var(--bg-3)" : "var(--bg-1)", color: v ? "var(--ink)" : "var(--ink-3)", fontSize: 12, textTransform: "uppercase", letterSpacing: ".06em", cursor: "pointer" };
              return (
              <button key={k} onClick={()=>setVisLayers(prev => ({...prev, [k]: !v}))}
                className="mono" style={_visLayerBtnStyle}>
                {v ? "✓" : " "} {k}
              </button>
              );
            })}
          </div>
        </div>
      </Panel>

      <div style={{ display: "grid", gridTemplateRows: "auto 1fr auto", gap: 14, minHeight: 0 }}>
        <Panel title="Part metadata">
          <div style={{ padding: 12, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
            {inspectorRows.map(([k,v]) => (
              <div key={k} style={{ minWidth: 0 }}>
                <div className="label">{k}</div>
                <div className="mono" style={{ fontSize: 12, color: "var(--ink-2)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{v}</div>
              </div>
            ))}
          </div>
        </Panel>

        <Panel title="Where-used">
          <table className="dtable">
            <thead><tr><th>Assembly</th><th>Qty</th><th>Program</th></tr></thead>
            <tbody>
              {whereUsedRows.map((r) => (
                <tr key={r[0]}><td>{r[0]}</td><td>{r[1]}</td><td>{r[2]}</td></tr>
              ))}
            </tbody>
          </table>
        </Panel>

        <Panel title="Linked artifacts">
          <div style={{ padding: 10, display: "flex", flexDirection: "column", gap: 6 }}>
            {(isTritan ? [
              ["QG-014",   "Motor no-load · CTQ-23",      "ok"],
              ["ECO-0042", "NRV body CI → S.G.-400",      "accent"],
              ["TPX-H-0008","Pump assy work instr",       "info"],
              ["WI-MOT-A", "Motor assembly work instr",   "info"],
            ] : [
              ["SIM-0411", "Static bending 1.5g · PASS", "info"],
              ["SIM-0412", "Modal · running 44%",        "warn"],
              ["ECO-2611", "L-7 → L-8 (fatigue margin)", "accent"],
              ["WI-210-B", "Rotor build work instruction","info"],
            ]).map(([a,b,t]) => (
              <div key={a} style={{ display: "grid", gridTemplateColumns: "90px 1fr", alignItems: "center", gap: 8 }}>
                <Pill tone={t}>{a}</Pill>
                <div style={{ fontSize: 12, color: "var(--ink-2)" }}>{b}</div>
              </div>
            ))}
          </div>
        </Panel>
      </div>
    </div>
  );
}

// Fake "3D" canvas — iso wireframe + stripe
function ViewerCanvas({ mode, visLayers, isTritan }) {
  return (
    <div style={{ position: "absolute", inset: 0, background: "radial-gradient(ellipse at 55% 45%, var(--bg-1) 0%, var(--bg-inset) 80%)", overflow: "hidden" }}>
      {/* grid floor */}
      <svg viewBox="0 0 1000 600" preserveAspectRatio="none" style={{ position:"absolute", inset: 0, width: "100%", height: "100%" }}>
        {/* horizon grid */}
        {Array.from({length: 14}).map((_, i) => (
          <line key={"h"+i} x1="0" y1={420 + i*12} x2="1000" y2={420 + i*12}
            stroke="var(--line-soft)" strokeWidth="0.5" opacity={1 - i*0.07} />
        ))}
        {Array.from({length: 24}).map((_, i) => {
          const x = 500 + (i-12) * 60;
          return <line key={"v"+i} x1={x} y1="420" x2={500 + (i-12) * 160} y2="600"
            stroke="var(--line-soft)" strokeWidth="0.5" />;
        })}
        {/* part: blade airfoil, stylized */}
        {visLayers.geom && (
          <g transform={`translate(500,300) ${mode==="front"?"scale(1.1,1.1)":mode==="top"?"scale(1.4,0.4)":"rotate(-18)"}`}>
            <defs>
              <linearGradient id="bladeG" x1="0" x2="1">
                <stop offset="0" stopColor="oklch(0.35 0.01 250)"/>
                <stop offset="1" stopColor="oklch(0.22 0.01 250)"/>
              </linearGradient>
            </defs>
            {/* blade silhouette */}
            <path d="M -300 0 C -280 -20, -80 -26, 140 -12 C 180 -9, 220 -4, 240 0 C 220 4, 180 8, 140 12 C -80 22, -280 16, -300 0 Z"
              fill="url(#bladeG)" stroke="var(--line-strong)" strokeWidth="1" />
            {/* chord lines */}
            {Array.from({length: 20}).map((_, i) => (
              <line key={i} x1={-300 + i*28} y1={-24} x2={-300 + i*28} y2={24}
                stroke="var(--line)" strokeWidth="0.5" opacity="0.55" />
            ))}
            {/* leading edge */}
            <path d="M -300 0 C -280 -20, -80 -26, 140 -12"
              stroke="var(--cool)" strokeWidth="1" fill="none" />
            {visLayers.mesh && (
              <g stroke="var(--accent)" strokeWidth="0.3" fill="none" opacity="0.75">
                {Array.from({length: 40}).map((_, i) => {
                  const x = -300 + i * 14;
                  return <g key={i}>
                    <line x1={x} y1="-22" x2={x+4} y2="22" />
                    <line x1={x+4} y1="22" x2={x+10} y2="-22" />
                  </g>;
                })}
              </g>
            )}
            {visLayers.bcs && (
              <g>
                {/* fixed support at root */}
                <rect x="-308" y="-30" width="12" height="60" fill="var(--warn)" opacity="0.25" stroke="var(--warn)" />
                <text x="-318" y="-34" className="mono" fontSize="9" fill="var(--warn)">FIX</text>
                {/* distributed load arrows */}
                {Array.from({length: 8}).map((_, i) => (
                  <g key={i} transform={`translate(${-240 + i*60}, -32)`}>
                    <line x1="0" y1="0" x2="0" y2="16" stroke="var(--accent)" strokeWidth="1"/>
                    <polygon points="0,20 -3,14 3,14" fill="var(--accent)"/>
                  </g>
                ))}
              </g>
            )}
          </g>
        )}
        {/* axis triad */}
        <g transform="translate(60, 540)">
          <line x1="0" y1="0" x2="26" y2="0" stroke="var(--err)" strokeWidth="1.2"/>
          <line x1="0" y1="0" x2="0" y2="-26" stroke="var(--ok)" strokeWidth="1.2"/>
          <line x1="0" y1="0" x2="-18" y2="18" stroke="var(--cool)" strokeWidth="1.2"/>
          <text x="28" y="4" fontSize="10" fill="var(--err)" className="mono">X</text>
          <text x="-4" y="-28" fontSize="10" fill="var(--ok)" className="mono">Z</text>
          <text x="-28" y="22" fontSize="10" fill="var(--cool)" className="mono">Y</text>
        </g>
      </svg>
      {visLayers.annot && (
        isTritan ? (
          <>
            <Anno top={90}  left={420} label="Rotor shaft Ø 18" />
            <Anno top={260} left={720} label="Stator bore 120" />
            <Anno top={360} left={160} label="Impeller W42" />
          </>
        ) : (
          <>
            <Anno top={90} left={420} label="LE radius · 12.0 mm" />
            <Anno top={260} left={720} label="tip chord · 310 mm" />
            <Anno top={360} left={160} label="root · 2.48 m · fiber 0°/±45°" />
          </>
        )
      )}
    </div>
  );
}
function Anno({ top, left, label }) {
  return (
    <div style={{ position: "absolute", top, left, display: "flex", alignItems: "center", gap: 6, pointerEvents: "none" }}>
      <div style={{ width: 6, height: 6, borderRadius: 6, background: "var(--accent)", boxShadow: "0 0 0 3px color-mix(in oklch, var(--accent) 30%, transparent)" }} />
      <div className="mono" style={{ fontSize: 12, color: "var(--ink-2)", background: "color-mix(in oklch, var(--bg-1) 80%, transparent)", padding: "2px 6px", border: "1px solid var(--line-soft)", borderRadius: 3 }}>{label}</div>
    </div>
  );
}
function ViewerOverlay({ mode }) {
  return (
    <div style={{ position: "absolute", top: 10, left: 10, display: "flex", gap: 10 }}>
      <div style={{ padding: "6px 10px", background: "color-mix(in oklch, var(--bg-1) 75%, transparent)", border: "1px solid var(--line-soft)", borderRadius: 4 }}>
        <div className="label">View</div>
        <div className="mono" style={{ fontSize: 12 }}>{mode.toUpperCase()} · mm · units mks</div>
      </div>
      <div style={{ padding: "6px 10px", background: "color-mix(in oklch, var(--bg-1) 75%, transparent)", border: "1px solid var(--line-soft)", borderRadius: 4 }}>
        <div className="label">Selection</div>
        <div className="mono" style={{ fontSize: 12 }}>surface · 142 faces</div>
      </div>
    </div>
  );
}

Object.assign(window, {
  ScreenDashboard,
  ScreenViewer,
});
