// Operator view — my apps, my deploys, my tests, one-click fixes.
const { useState, useMemo } = React;
const { Pill, OwnerChip, Sparkbars, AppGlyph, currency } = window;
const { AppTile } = window;
const { Icons, DATA } = window;

function OperatorView({ onOpenApp, onRequestApproval, onNav, onShipNew, onNewTest }) {
  const me = DATA.ME_OPERATOR;
  const myApps = DATA.APPS.filter(a => a.owner === me.id);
  const myDau = myApps.reduce((s,a) => s + a.dau, 0);
  const myWau = myApps.reduce((s,a) => s + a.wau, 0);
  const myTestsPass = myApps.reduce((s,a) => s + a.tests.passing, 0);
  const myTestsTotal = myApps.reduce((s,a) => s + a.tests.total, 0);

  return (
    <div className="fade-in">
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", marginBottom: 28, gap: 24 }}>
        <div>
          <div className="eyebrow">Operator · {me.team}</div>
          <h1 className="page-title" style={{ marginTop: 8 }}>
            Good morning, <em>Maya.</em>
          </h1>
          <p className="page-sub">{myDau} people using your apps today. One change caught by a test overnight — rollback already staged.</p>
        </div>
        <div style={{ display: "flex", gap: 10 }}>
          <button className="btn" onClick={() => onNewTest && onNewTest()}><Icons.Record/> Record a workflow test</button>
          <button className="btn accent" onClick={() => onShipNew && onShipNew()}><Icons.Plus/> Ship new app</button>
        </div>
      </div>

      <div className="card" style={{ marginBottom: 20, borderColor: "var(--red-border)", background: "var(--red-bg)" }}>
        <div style={{ display: "flex", gap: 14, alignItems: "flex-start" }}>
          <div className="worry" style={{ padding: 0, borderBottom: "none" }}>
            <div className="icon risk"><Icons.Alert/></div>
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: "var(--mono)", fontSize: 11, textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--red)" }}>
              Stoda held this deploy — your test caught it
            </div>
            <h3 style={{ fontSize: 17, color: "var(--ink)", marginTop: 4, fontWeight: 500 }}>
              Quote Copilot v124 — test <span className="sig" style={{ fontSize: 14, background: "var(--paper)", padding: "2px 6px", borderRadius: 4 }}>quote totals match Salesforce</span> failed
            </h3>
            <p style={{ color: "var(--ink-3)", fontSize: 13.5, marginTop: 8, maxWidth: "70ch", lineHeight: 1.55 }}>
              On staging, the rounding branch returned <span className="sig">$12,488.00</span> where Salesforce expects <span className="sig">$12,488.50</span>. Likely introduced by a change to <span className="sig">lib/pricing.ts</span> at <span className="sig">8f3a1c4</span>.
            </p>
            <div style={{ display: "flex", gap: 8, marginTop: 14, flexWrap: "wrap" }}>
              <button className="btn primary sm"><Icons.Rollback s={12}/> Rollback to v123</button>
              <button className="btn sm"><Icons.Flask s={12}/> Ask Stoda for a fix</button>
              <button className="btn sm"><Icons.Play s={12}/> Replay on recorded data</button>
              <button className="btn ghost sm"><Icons.ExternalLink s={12}/> Open diff</button>
            </div>
          </div>
        </div>
      </div>

      <div className="grid g-4" style={{ marginBottom: 20 }}>
        <div className="card kpi">
          <div className="label">MAU across my apps</div>
          <div className="value">{myApps.reduce((s,a) => s + (a.uniqueMau || a.monthlyUsers || 0), 0)}</div>
          <div className="delta pos">+14% vs last month</div>
        </div>
        <div className="card kpi">
          <div className="label">Apps I own</div>
          <div className="value">{myApps.length}</div>
          <div style={{ marginTop: 12, fontSize: 11.5, color: "var(--muted)" }}>
            <span className="sig" style={{ background: "var(--red-bg)", color: "var(--red)", padding: "1px 6px", borderRadius: 4 }}>1 stuck in staging</span>
          </div>
        </div>
        <div className="card kpi">
          <div className="label">Tests passing</div>
          <div className="value">{myTestsPass}<span className="unit" style={{ color: "var(--muted)" }}>/{myTestsTotal}</span></div>
          <div className="delta" style={{ color: "var(--red)" }}>1 failing on staging</div>
        </div>
        <div className="card kpi">
          <div className="label">Deploys this week</div>
          <div className="value">{myApps.reduce((s,a)=>s+a.deploys7d,0)}</div>
          <div style={{ marginTop: 12 }}><Sparkbars values={DATA.SPARK(47)}/></div>
        </div>
      </div>

      <div style={{ marginBottom: 22 }}>
        <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", marginBottom: 10 }}>
          <h3 style={{ fontSize: 15, color: "var(--ink)" }}>My apps</h3>
          <div style={{ fontSize: 12, color: "var(--muted)" }}>Sorted by last-deployed</div>
        </div>
        <div className="grid g-3">
          {myApps.map(a => <AppTile key={a.id} app={a} onOpen={onOpenApp}/>)}
          <button onClick={() => onShipNew && onShipNew()} className="app-tile" style={{ border: "1px dashed var(--tan)", background: "transparent", justifyContent: "center", alignItems: "center", color: "var(--muted)", minHeight: 180, cursor: "pointer", fontFamily: "inherit", textAlign: "center" }}>
            <div style={{ textAlign: "center" }}>
              <div style={{ width: 34, height: 34, margin: "0 auto 8px", borderRadius: 10, background: "var(--cream-3)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--ink-3)" }}>
                <Icons.Plus/>
              </div>
              <div style={{ fontSize: 13, color: "var(--ink-3)", fontWeight: 500 }}>Ship a new app</div>
              <div style={{ fontSize: 11.5, marginTop: 4 }}>Generate anywhere · ship through Stoda</div>
            </div>
          </button>
        </div>
      </div>

      <div className="grid g-12" style={{ marginBottom: 20 }}>
        <div className="col-7 card flush">
          <div className="card-head" style={{ padding: "18px 20px 12px", marginBottom: 0 }}>
            <div>
              <h3>Recent deploys</h3>
              <div className="subtitle">Every deploy that touched my apps.</div>
            </div>
            <button className="btn sm" onClick={() => onNav && onNav("fleet")}>Open fleet <Icons.Arrow s={12}/></button>
          </div>
          <div>
            {[
              { app: "Quote Copilot",     v: "v124", state: "held",    when: "14m ago", commit: "8f3a1c4", note: "tests failed — rollback staged" },
              { app: "Onboarding Wizard", v: "v041", state: "shipped", when: "7h ago",  commit: "2e9f90a", note: "all 15 tests green" },
              { app: "Quote Copilot",     v: "v123", state: "shipped", when: "yesterday", commit: "bc04211", note: "38 tests · 12s" },
              { app: "Onboarding Wizard", v: "v040", state: "shipped", when: "yesterday", commit: "775a0d2", note: "auto-merged dependency bump" },
              { app: "Quote Copilot",     v: "v122", state: "shipped", when: "2d ago",  commit: "a912ef1", note: "shipped by Stoda at 03:14" },
            ].map((d, i) => (
              <div key={i} className="row">
                <div style={{ display: "flex", alignItems: "center", gap: 12, minWidth: 0 }}>
                  <span style={{ width: 6, height: 6, borderRadius: "50%", background: d.state === "held" ? "var(--red)" : "var(--green)" }}/>
                  <div style={{ minWidth: 0 }}>
                    <div className="primary">{d.app} <span className="sig">{d.v}</span></div>
                    <div className="secondary">{d.note} · <span className="sig">{d.commit}</span></div>
                  </div>
                </div>
                <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                  {d.state === "held"
                    ? <Pill kind="risk">held</Pill>
                    : <Pill kind="ok">shipped</Pill>}
                  <span className="secondary" style={{ minWidth: 80, textAlign: "right" }}>{d.when}</span>
                </div>
              </div>
            ))}
          </div>
        </div>

        <div className="col-5 card">
          <div className="card-head">
            <div>
              <h3>Tests I've authored</h3>
              <div className="subtitle">Recorded once. Replayed on every deploy.</div>
            </div>
            <button className="btn sm" onClick={() => onNav && onNav("tests")}>See all <Icons.Arrow s={12}/></button>
          </div>

          <div style={{ fontSize: 12, color: "var(--muted)", marginBottom: 8 }}>Active tests</div>
          {[
            { n: "quote totals match Salesforce",    app: "Quote Copilot",     runs: 142, ok: true,  last: "12s" },
            { n: "PDF render ≤ 3s p95",              app: "Quote Copilot",     runs: 142, ok: true,  last: "27s" },
            { n: "onboarding completes in 4 steps",  app: "Onboarding Wizard", runs: 38,  ok: true,  last: "9s" },
            { n: "CRM sync round-trip",              app: "Onboarding Wizard", runs: 38,  ok: false, last: "failed" },
          ].map((t, i) => (
            <div key={i} style={{ display: "flex", alignItems: "center", gap: 12, padding: "10px 0", borderBottom: i === 3 ? "none" : "1px solid var(--tan-2)" }}>
              <span style={{ width: 8, height: 8, borderRadius: "50%", background: t.ok ? "var(--green)" : "var(--red)" }}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, color: "var(--ink)", fontWeight: 500 }}>{t.n}</div>
                <div style={{ fontSize: 11.5, color: "var(--muted)" }}>{t.app} · {t.runs} runs · last {t.last}</div>
              </div>
              <button className="btn ghost sm"><Icons.Play s={11}/></button>
            </div>
          ))}
        </div>
      </div>

      <div className="grid g-2" style={{ marginBottom: 20 }}>
        <div className="card">
          <div className="card-head">
            <div>
              <h3>One-click fixes</h3>
              <div className="subtitle">Safe improvements Stoda is confident about.</div>
            </div>
          </div>
          {[
            { r: "Dependency 30+ days stale",              where: "Onboarding Wizard",              fix: "Auto-apply tested bundle", sev: "warn", one: true },
            { r: "Quote Copilot shares OPENAI_API_KEY",    where: "Split by Jun 12 to keep deploys", fix: "Generate per-app key",     sev: "warn", one: true },
            { r: "Quote Copilot called api.salesforce.com 4d ago", where: "First-seen — your CTO will see this on Connections", fix: "Request allowlist", sev: "warn", one: false },
          ].map((r, i) => (
            <div key={i} style={{ display: "flex", alignItems: "flex-start", gap: 12, padding: "14px 0", borderBottom: i === 2 ? "none" : "1px solid var(--tan-2)" }}>
              <Pill kind={r.sev}>rule</Pill>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ color: "var(--ink)", fontWeight: 500, fontSize: 13.5 }}>{r.r}</div>
                <div style={{ color: "var(--muted)", fontSize: 12 }}>{r.where}</div>
              </div>
              {r.one
                ? <button className="btn primary sm">{r.fix}</button>
                : <button className="btn sm" onClick={onRequestApproval}>{r.fix} <Icons.Arrow s={12}/></button>}
            </div>
          ))}
        </div>

        <div className="card">
          <div className="card-head">
            <div>
              <h3>Approvals I've requested</h3>
              <div className="subtitle">Routed to the CTO inbox.</div>
            </div>
          </div>
          {[
            { what: "Add outbound domain api.stripe.com",  state: "pending",  when: "12m" },
            { what: "Increase LLM budget by $500",          state: "pending",  when: "3h" },
            { what: "Rotate shared key OPENAI_API_KEY",     state: "approved", when: "2d" },
          ].map((a, i) => (
            <div key={i} style={{ display: "flex", alignItems: "center", gap: 12, padding: "14px 0", borderBottom: i === 2 ? "none" : "1px solid var(--tan-2)" }}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ color: "var(--ink)", fontSize: 13.5, fontWeight: 500 }}>{a.what}</div>
                <div style={{ color: "var(--muted)", fontSize: 12 }}>Reviewer: Priya Rangarajan · {a.when}</div>
              </div>
              {a.state === "pending" ? <Pill kind="warn">awaiting</Pill> : <Pill kind="ok">approved</Pill>}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ---------- Operator Costs page — scoped to my apps, no team budgets ----------
function OperatorCostsPage({ onOpenApp, onOpenBudget }) {
  const me = DATA.ME_OPERATOR;
  const myApps = DATA.APPS.filter(a => a.owner === me.id);
  const totalSpent = myApps.reduce((s, a) => s + a.cost, 0);
  const totalBudget = myApps.reduce((s, a) => s + (a.budget || a.cost * 1.4), 0);
  const pct = Math.round((totalSpent / totalBudget) * 100);
  const trend = DATA.COST_TREND_30D || DATA.SPARK(31);
  const maxTrend = Math.max(...trend);

  return (
    <div className="fade-in">
      <div style={{ marginBottom: 22 }}>
        <div className="eyebrow">My costs · April 2026 · Month-to-date</div>
        <h1 className="page-title" style={{ marginTop: 8 }}>Spending across <em>your apps.</em></h1>
        <p className="page-sub">Just the apps you own. Your CTO sees fleet-wide attribution; this is what hits your budgets.</p>
      </div>

      <div className="cost-topline">
        <div className="cost-top-card">
          <div className="cost-top-label">Spend this month</div>
          <div className="cost-top-value">${(totalSpent/1000).toFixed(2)}k</div>
          <div className="cost-top-foot">of ${(totalBudget/1000).toFixed(2)}k budgeted ({pct}%)</div>
          <div className="cost-bar"><div className="cost-bar-fill" style={{ width: `${pct}%` }}/></div>
        </div>
        <div className="cost-top-card">
          <div className="cost-top-label">Forecast · end of month</div>
          <div className="cost-top-value">${((totalSpent * 30/27)/1000).toFixed(2)}k</div>
          <div className="cost-top-foot pos">on track</div>
          <div className="cost-bar"><div className="cost-bar-fill proj" style={{ width: `${Math.round((totalSpent*30/27)/totalBudget*100)}%` }}/></div>
        </div>
        <div className="cost-top-card">
          <div className="cost-top-label">Apps you own</div>
          <div className="cost-top-value">{myApps.length}</div>
          <div className="cost-top-foot">{myApps.reduce((s,a) => s + a.monthlyUsers, 0)} monthly users · {myApps.reduce((s,a) => s + a.deploys7d, 0)} deploys / 7d</div>
        </div>
      </div>

      <div className="grid g-12" style={{ marginTop: 20, gap: 16 }}>
        <div className="col-7 card flush">
          <div className="card-head" style={{ padding: "18px 20px 12px", marginBottom: 0 }}>
            <div>
              <h3>Per-app spend</h3>
              <div className="subtitle">Click a row to see the budget breakdown.</div>
            </div>
          </div>
          <table className="t">
            <thead><tr><th>App</th><th>Spend</th><th>Budget</th><th>Headroom</th><th></th></tr></thead>
            <tbody>
              {myApps.map(a => {
                const budget = a.budget || Math.round(a.cost * 1.4);
                const aPct = Math.round((a.cost / budget) * 100);
                const headroom = budget - a.cost;
                const tone = aPct >= 85 ? "risk" : aPct >= 70 ? "warn" : "ok";
                return (
                  <tr key={a.id} style={{ cursor: "pointer" }} onClick={() => onOpenApp(a)}>
                    <td>
                      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                        <AppGlyph name={a.name} bg={DATA.OPERATORS[a.owner]?.color}/>
                        <span style={{ fontSize: 13, color: "var(--ink)", fontWeight: 500 }}>{a.name}</span>
                      </div>
                    </td>
                    <td style={{ fontFamily: "var(--mono)", fontSize: 12.5, color: "var(--ink)" }}>${a.cost.toLocaleString()}</td>
                    <td style={{ fontFamily: "var(--mono)", fontSize: 12.5, color: "var(--muted)" }}>${budget.toLocaleString()}</td>
                    <td>
                      <div style={{ display: "flex", alignItems: "center", gap: 10, minWidth: 160 }}>
                        <div style={{ flex: 1, height: 5, background: "var(--cream-3)", borderRadius: 3, overflow: "hidden" }}>
                          <div style={{ width: `${aPct}%`, height: "100%", background: tone === "risk" ? "var(--red)" : tone === "warn" ? "var(--orange)" : "var(--green)" }}/>
                        </div>
                        <span style={{ fontSize: 11.5, color: "var(--muted)", fontFamily: "var(--mono)", minWidth: 36 }}>{aPct}%</span>
                      </div>
                    </td>
                    <td style={{ textAlign: "right" }}>
                      <button className="btn ghost sm" onClick={(e) => { e.stopPropagation(); onOpenBudget(); }}>
                        {headroom < 200 ? "Request more" : "Budget"} <Icons.Arrow s={11}/>
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        <div className="col-5 card">
          <div className="card-head">
            <div>
              <h3>30-day spend</h3>
              <div className="subtitle">Across your apps.</div>
            </div>
          </div>
          <div style={{ display: "flex", alignItems: "flex-end", gap: 3, height: 88, marginTop: 10 }}>
            {trend.slice(-30).map((v, i) => (
              <div key={i} style={{ flex: 1, height: `${(v/maxTrend)*100}%`, background: i >= 27 ? "var(--orange)" : "var(--ink-3)", opacity: i >= 27 ? 1 : 0.3, borderRadius: 1, minHeight: 2 }}/>
            ))}
          </div>
          <div style={{ display: "flex", justifyContent: "space-between", fontSize: 11, color: "var(--muted)", marginTop: 8, fontFamily: "var(--mono)" }}>
            <span>Mar 7</span><span>Mar 21</span><span>Apr 6</span>
          </div>

          <div style={{ marginTop: 18, padding: 14, background: "var(--cream-2)", border: "1px solid var(--tan-2)", borderRadius: 8 }}>
            <div style={{ fontSize: 12.5, color: "var(--ink)", fontWeight: 500 }}>Quote Copilot shares OPENAI_API_KEY</div>
            <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 4, lineHeight: 1.5 }}>
              Spend on this key isn't pinned to your app yet. Your CTO is rolling out per-app keys by Jun 12.
            </div>
            <button className="btn sm" style={{ marginTop: 10 }}>Generate per-app key <Icons.Arrow s={11}/></button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ---------- Operator Tests page ----------
function OperatorTestsPage({ onOpenApp, onNewTest }) {
  const me = DATA.ME_OPERATOR;
  const myApps = DATA.APPS.filter(a => a.owner === me.id);
  const totalTests = myApps.reduce((s,a) => s + a.tests.total, 0);
  const passingTests = myApps.reduce((s,a) => s + a.tests.passing, 0);
  const failing = [];
  myApps.forEach(a => {
    const fails = a.tests.failing || [];
    fails.forEach(f => failing.push({ app: a, name: f }));
  });

  // Synthesize a list of every test across my apps.
  const allTests = useMemo(() => {
    const rows = [];
    const sampleNames = [
      "happy path: standard quote · 5 seats",
      "enterprise net-30 terms applied",
      "discount cap enforced at 35%",
      "PII redacted from prompt logs",
      "Stripe webhook signature verifies",
      "duplicate quote returns cached row",
      "PDF render ≤ 3s p95",
      "Salesforce sync round-trip",
      "rate limit retries with backoff",
      "missing customer_type defaults to standard",
      "audit log written on every send",
      "checkout idempotency on double-submit",
      "currency rounds to nearest cent",
      "session expires after 30m idle",
      "error states render fallback UI",
      "webhook receiver tolerates out-of-order events",
      "feature flag overrides per-tenant",
      "background job survives restart",
      "image upload caps at 5MB",
      "search returns within 200ms p95",
    ];
    let i = 0;
    myApps.forEach(app => {
      const failNames = new Set(app.tests.failing || []);
      // Failing tests first
      (app.tests.failing || []).forEach(name => {
        rows.push({ id: `${app.id}-${i++}`, app, name, status: "fail", env: "staging", runs: 12 + (i*7)%80, lastRun: "12m ago", duration: (1 + (i%5)*0.4).toFixed(1) + "s", author: me.name });
      });
      // Passing tests
      const numPassing = app.tests.passing;
      for (let k = 0; k < numPassing; k++) {
        const name = sampleNames[(k + app.id.length*3) % sampleNames.length];
        if (failNames.has(name)) continue;
        const env = k % 4 === 0 ? "staging" : "prod";
        const hours = (k * 3 + 1) % 30;
        rows.push({
          id: `${app.id}-${i++}`,
          app, name,
          status: "pass", env,
          runs: 30 + (k*11) % 200,
          lastRun: hours < 1 ? "just now" : hours === 1 ? "1h ago" : `${hours}h ago`,
          duration: (0.2 + (k%6)*0.3).toFixed(1) + "s",
          author: me.name,
        });
      }
    });
    return rows;
  }, [myApps]);

  const [appFilter, setAppFilter] = useState("all"); // 'all' | app.id
  const [statusFilter, setStatusFilter] = useState("all"); // 'all' | 'pass' | 'fail'
  const [q, setQ] = useState("");

  const visibleTests = allTests.filter(t => {
    if (appFilter !== "all" && t.app.id !== appFilter) return false;
    if (statusFilter !== "all" && t.status !== statusFilter) return false;
    if (q.trim()) {
      const n = q.trim().toLowerCase();
      if (!t.name.toLowerCase().includes(n) && !t.app.name.toLowerCase().includes(n)) return false;
    }
    return true;
  });

  // Mock recent passing runs
  const recentRuns = [
    { app: myApps[0], name: "quote totals match Salesforce", env: "staging", when: "12m ago", status: "fail", duration: "3.2s" },
    { app: myApps[0], name: "Stripe webhook signature verifies", env: "prod", when: "1h ago", status: "pass", duration: "0.8s" },
    { app: myApps[0], name: "discount cap enforced at 35%", env: "prod", when: "1h ago", status: "pass", duration: "0.4s" },
    { app: myApps[1], name: "churn score within 5% of baseline", env: "prod", when: "3h ago", status: "pass", duration: "2.1s" },
    { app: myApps[2], name: "duplicate quotes return cached row", env: "prod", when: "5h ago", status: "pass", duration: "0.3s" },
    { app: myApps[0], name: "PII redacted from prompt logs", env: "prod", when: "8h ago", status: "pass", duration: "1.1s" },
  ];

  return (
    <div className="fade-in">
      <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", marginBottom: 22, gap: 24 }}>
        <div>
          <div className="eyebrow">Tests · across {myApps.length} apps I own</div>
          <h1 className="page-title" style={{ marginTop: 8 }}>
            {failing.length > 0 ? <>1 test <em>failing.</em></> : <>All <em>green.</em></>}
          </h1>
          <p className="page-sub">{passingTests} of {totalTests} passing across your apps. Failing tests block deploys to that environment.</p>
        </div>
        <button className="btn accent" onClick={() => onNewTest && onNewTest()} style={{ flexShrink: 0 }}><Icons.Record/> Record a workflow test</button>
      </div>

      <div className="grid g-4" style={{ marginBottom: 20 }}>
        <div className="card kpi">
          <div className="label">Total tests</div>
          <div className="value">{totalTests}</div>
          <div style={{ marginTop: 12, fontSize: 11.5, color: "var(--muted)" }}>across {myApps.length} apps</div>
        </div>
        <div className="card kpi">
          <div className="label">Passing</div>
          <div className="value" style={{ color: "var(--green)" }}>{passingTests}</div>
          <div className="delta pos">{Math.round(passingTests/totalTests*100)}% pass rate</div>
        </div>
        <div className="card kpi">
          <div className="label">Failing</div>
          <div className="value" style={{ color: failing.length ? "var(--red)" : "var(--ink)" }}>{failing.length}</div>
          <div style={{ marginTop: 12, fontSize: 11.5, color: "var(--muted)" }}>{failing.length ? "blocking 1 deploy" : "nothing blocked"}</div>
        </div>
        <div className="card kpi">
          <div className="label">Runs (7d)</div>
          <div className="value">412</div>
          <div style={{ marginTop: 12 }}><Sparkbars values={DATA.SPARK(31)}/></div>
        </div>
      </div>

      {failing.length > 0 && (
        <div className="card" style={{ marginBottom: 20, borderColor: "var(--red-border)" }}>
          <div className="card-head">
            <div className="card-title">Failing tests</div>
            <span className="sig" style={{ background: "var(--red-bg)", color: "var(--red)" }}>{failing.length} blocking</span>
          </div>
          {failing.map((f, i) => (
            <div key={i} style={{ display: "flex", alignItems: "center", gap: 14, padding: "14px 0", borderTop: i ? "1px solid var(--tan-2)" : "none" }}>
              <AppGlyph name={f.app.name} bg={DATA.OPERATORS[f.app.owner]?.color}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13.5, color: "var(--ink)", fontWeight: 500 }}>{f.name}</div>
                <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 3 }}>
                  {f.app.name} · staging · failed 12m ago · holding deploy of v{f.app.stagedVersion?.replace("v","") || "124"}
                </div>
              </div>
              <button className="btn sm" onClick={() => onOpenApp(f.app)}>Open in app</button>
              <button className="btn sm">Re-run</button>
            </div>
          ))}
        </div>
      )}

      <div className="card flush" style={{ marginBottom: 20 }}>
        <div className="card-head" style={{ padding: "14px 16px", marginBottom: 0 }}>
          <div className="card-title">Coverage by app</div>
        </div>
        <table className="t">
          <thead><tr><th>App</th><th style={{ width: "30%" }}>Coverage</th><th style={{ textAlign: "right" }}>Tests</th><th style={{ textAlign: "right" }}>Last run</th></tr></thead>
          <tbody>
            {myApps.map(a => {
              const pct = a.tests.passing / a.tests.total;
              const allPass = a.tests.passing === a.tests.total;
              return (
                <tr key={a.id} onClick={() => onOpenApp(a)} style={{ cursor: "pointer" }}>
                  <td>
                    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                      <AppGlyph name={a.name} bg={DATA.OPERATORS[a.owner]?.color}/>
                      <div style={{ fontSize: 13, color: "var(--ink)", fontWeight: 500 }}>{a.name}</div>
                    </div>
                  </td>
                  <td>
                    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                      <div style={{ flex: 1, height: 6, background: "var(--tan-2)", borderRadius: 3, overflow: "hidden" }}>
                        <div style={{ width: `${pct*100}%`, height: "100%", background: allPass ? "var(--green)" : "var(--red)" }}/>
                      </div>
                      <span style={{ fontSize: 12, color: "var(--muted)", fontVariantNumeric: "tabular-nums", width: 36, textAlign: "right" }}>{Math.round(pct*100)}%</span>
                    </div>
                  </td>
                  <td style={{ textAlign: "right", fontVariantNumeric: "tabular-nums", color: allPass ? "var(--green)" : "var(--red)" }}>{a.tests.passing}/{a.tests.total}</td>
                  <td style={{ textAlign: "right", fontSize: 12, color: "var(--muted)" }}>{a.lastDeploy}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      <div className="card flush" style={{ marginBottom: 20 }}>
        <div className="card-head" style={{ padding: "14px 16px", marginBottom: 0, gap: 10, flexWrap: "wrap" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
            <div className="card-title">All tests</div>
            <div style={{ display: "flex", gap: 4, padding: 2, background: "var(--cream-3)", borderRadius: 7 }}>
              {[["all", "All"], ["pass", "Passing"], ["fail", "Failing"]].map(([k, l]) => (
                <button key={k} onClick={() => setStatusFilter(k)}
                  style={{
                    padding: "5px 10px", fontSize: 11.5, fontWeight: 500,
                    border: "none", borderRadius: 5,
                    background: statusFilter === k ? "var(--paper)" : "transparent",
                    color: statusFilter === k ? "var(--ink)" : "var(--muted)",
                    cursor: "pointer", fontFamily: "inherit",
                    boxShadow: statusFilter === k ? "0 1px 2px rgba(0,0,0,.04)" : "none",
                  }}>{l}</button>
              ))}
            </div>
            <div style={{ display: "flex", gap: 4, padding: 2, background: "var(--cream-3)", borderRadius: 7 }}>
              <button onClick={() => setAppFilter("all")}
                style={{
                  padding: "5px 10px", fontSize: 11.5, fontWeight: 500,
                  border: "none", borderRadius: 5,
                  background: appFilter === "all" ? "var(--paper)" : "transparent",
                  color: appFilter === "all" ? "var(--ink)" : "var(--muted)",
                  cursor: "pointer", fontFamily: "inherit",
                  boxShadow: appFilter === "all" ? "0 1px 2px rgba(0,0,0,.04)" : "none",
                }}>All apps</button>
              {myApps.map(a => (
                <button key={a.id} onClick={() => setAppFilter(a.id)}
                  style={{
                    padding: "5px 10px", fontSize: 11.5, fontWeight: 500,
                    border: "none", borderRadius: 5,
                    background: appFilter === a.id ? "var(--paper)" : "transparent",
                    color: appFilter === a.id ? "var(--ink)" : "var(--muted)",
                    cursor: "pointer", fontFamily: "inherit",
                    boxShadow: appFilter === a.id ? "0 1px 2px rgba(0,0,0,.04)" : "none",
                  }}>{a.name}</button>
              ))}
            </div>
            <div style={{ position: "relative", display: "flex", alignItems: "center" }}>
              <span style={{ position: "absolute", left: 10, color: "var(--muted-2)", display: "flex" }}><Icons.Search s={12}/></span>
              <input value={q} onChange={e => setQ(e.target.value)} placeholder="Search tests…"
                style={{ fontFamily: "inherit", fontSize: 12.5, padding: "6px 12px 6px 28px", width: 200,
                  background: "var(--paper)", color: "var(--ink)", border: "1px solid var(--tan-2)", borderRadius: 7, outline: "none" }}/>
            </div>
          </div>
          <span className="tag">{visibleTests.length} of {allTests.length}</span>
        </div>
        <table className="t">
          <thead><tr><th>Test</th><th>App</th><th>Env</th><th style={{ textAlign: "right" }}>Runs</th><th style={{ textAlign: "right" }}>Duration</th><th style={{ textAlign: "right" }}>Last run</th><th style={{ width: 100 }}></th></tr></thead>
          <tbody>
            {visibleTests.length === 0 && (
              <tr><td colSpan={7} style={{ textAlign: "center", padding: 32, color: "var(--muted)", fontSize: 12.5 }}>No tests match these filters.</td></tr>
            )}
            {visibleTests.map(t => (
              <tr key={t.id} onClick={() => onOpenApp(t.app)} style={{ cursor: "pointer" }}>
                <td>
                  <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                    <span style={{ width: 7, height: 7, borderRadius: "50%", background: t.status === "pass" ? "var(--green)" : "var(--red)", flexShrink: 0 }}/>
                    <span style={{ fontSize: 12.5, color: "var(--ink)" }}>{t.name}</span>
                  </div>
                </td>
                <td style={{ fontSize: 12, color: "var(--muted)" }}>{t.app.name}</td>
                <td><span className="tag">{t.env}</span></td>
                <td style={{ textAlign: "right", fontSize: 12, color: "var(--muted)", fontVariantNumeric: "tabular-nums" }}>{t.runs}</td>
                <td style={{ textAlign: "right", fontSize: 12, color: "var(--muted)", fontVariantNumeric: "tabular-nums" }}>{t.duration}</td>
                <td style={{ textAlign: "right", fontSize: 12, color: "var(--muted)" }}>{t.lastRun}</td>
                <td style={{ textAlign: "right" }} onClick={e => e.stopPropagation()}>
                  <button className="btn ghost sm" title="Re-run"><Icons.Play s={11}/></button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <div className="card flush">
        <div className="card-head" style={{ padding: "14px 16px", marginBottom: 0 }}>
          <div className="card-title">Recent runs</div>
          <span className="tag">last 24h</span>
        </div>
        <table className="t">
          <thead><tr><th>Test</th><th>App</th><th>Env</th><th style={{ textAlign: "right" }}>Duration</th><th style={{ textAlign: "right" }}>When</th><th style={{ textAlign: "right", width: 60 }}></th></tr></thead>
          <tbody>
            {recentRuns.map((r, i) => (
              <tr key={i} onClick={() => onOpenApp(r.app)} style={{ cursor: "pointer" }}>
                <td style={{ fontSize: 12.5, color: "var(--ink)" }}>{r.name}</td>
                <td style={{ fontSize: 12, color: "var(--muted)" }}>{r.app.name}</td>
                <td><span className="tag">{r.env}</span></td>
                <td style={{ textAlign: "right", fontSize: 12, color: "var(--muted)", fontVariantNumeric: "tabular-nums" }}>{r.duration}</td>
                <td style={{ textAlign: "right", fontSize: 12, color: "var(--muted)" }}>{r.when}</td>
                <td style={{ textAlign: "right" }}>
                  <Pill kind={r.status === "pass" ? "ok" : "risk"}>{r.status}</Pill>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

window.OperatorView = OperatorView;
window.OperatorCostsPage = OperatorCostsPage;
window.OperatorTestsPage = OperatorTestsPage;