// CTO Template page — what's in the org's template repo + auto-generated update recommendations.
const { useState: useStateT } = React;
const { Pill: PillT, AppGlyph: AppGlyphT } = window;
const { Icons: IconsT, DATA: DATAT } = window;

function TemplatePage({ onOpenApp }) {
  const [acceptedRecs, setAcceptedRecs] = useStateT({});
  const [optedOut, setOptedOut] = useStateT(false);

  const accept = (id) => setAcceptedRecs(p => ({ ...p, [id]: true }));
  const reject = (id) => setAcceptedRecs(p => ({ ...p, [id]: "rejected" }));

  return (
    <div className="fade-in">
      <div style={{ marginBottom: 24 }}>
        <div className="eyebrow">Template · meridia/app-template · v4.2.1 · 24 apps using this</div>
        <h1 className="page-title" style={{ marginTop: 8 }}>The <em>template.</em></h1>
        <p className="page-sub">What every new app at Meridia starts from. Skills, dependencies, and base prompts that encode how we build here. Three updates queued from fleet learnings.</p>
      </div>

      <div className="grid g-4" style={{ marginBottom: 24 }}>
        <div className="card kpi">
          <div className="label">Apps on this template</div>
          <div className="value">24<span className="unit" style={{ color: "var(--muted)" }}>/24</span></div>
          <div className="delta pos">100% adoption</div>
        </div>
        <div className="card kpi">
          <div className="label">Current version</div>
          <div className="value" style={{ fontFamily: "var(--mono, ui-monospace)" }}>v4.2.1</div>
          <div style={{ marginTop: 12, fontSize: 11.5, color: "var(--muted)" }}>shipped 11 days ago</div>
        </div>
        <div className="card kpi">
          <div className="label">Pending updates</div>
          <div className="value" style={{ color: "var(--amber)" }}>3</div>
          <div style={{ marginTop: 12, fontSize: 11.5, color: "var(--muted)" }}>auto-drafted from fleet</div>
        </div>
        <div className="card kpi">
          <div className="label">Avg audit on template apps</div>
          <div className="value">82</div>
          <div className="delta pos">+6 vs non-template</div>
        </div>
      </div>

      {/* What's in it */}
      <div className="card flush" style={{ marginBottom: 24 }}>
        <div className="card-head" style={{ padding: "16px 18px 14px", marginBottom: 0 }}>
          <div>
            <div className="card-title">What's in the template</div>
            <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 3 }}>Every new app inherits these defaults. Operators can override per-app, but the template is the floor.</div>
          </div>
          <button className="btn sm"><IconsT.Github/> View on GitHub</button>
        </div>

        <div style={{ padding: "0 18px 18px", display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
          {/* Skills */}
          <div style={{ border: "1px solid var(--tan-2)", borderRadius: 10, padding: 16, background: "var(--cream-3)" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }}>
              <IconsT.Spark s={14}/>
              <div style={{ fontSize: 12, fontWeight: 600, color: "var(--ink)", textTransform: "uppercase", letterSpacing: 0.4 }}>Skills</div>
              <span className="tag" style={{ marginLeft: "auto" }}>5</span>
            </div>
            {[
              ["pii-redaction",       "Strips emails, phones, SSNs from prompts before LLM calls"],
              ["audit-log",           "Append-only event log to S3 with 7-year retention"],
              ["budget-guard",        "Per-app cost ceiling with circuit breaker at 90%"],
              ["staged-deploy",       "Operator tests must pass on staging before prod cutover"],
              ["secret-rotation",     "Vault refresh, no env-baked secrets"],
            ].map(([n, d]) => (
              <div key={n} style={{ display: "flex", gap: 10, padding: "8px 0", borderTop: "1px solid var(--tan-2)" }}>
                <span style={{ fontFamily: "var(--mono, ui-monospace)", fontSize: 11.5, color: "var(--ink)", minWidth: 140 }}>{n}</span>
                <span style={{ fontSize: 12, color: "var(--muted)", flex: 1 }}>{d}</span>
              </div>
            ))}
          </div>

          {/* Dependencies */}
          <div style={{ border: "1px solid var(--tan-2)", borderRadius: 10, padding: 16, background: "var(--cream-3)" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }}>
              <IconsT.Box s={14}/>
              <div style={{ fontSize: 12, fontWeight: 600, color: "var(--ink)", textTransform: "uppercase", letterSpacing: 0.4 }}>Approved dependencies</div>
              <span className="tag" style={{ marginLeft: "auto" }}>9</span>
            </div>
            {[
              ["@anthropic-ai/sdk",  "0.27.x", "LLM"],
              ["openai",             "4.55.x", "LLM"],
              ["stripe",             "16.2.x", "API"],
              ["@salesforce/jsforce","3.1.x",  "API"],
              ["@hubspot/api-client","11.x",   "API"],
              ["pg",                 "8.11.x", "DB"],
              ["next",               "14.2.x", "framework"],
              ["zod",                "3.23.x", "validation"],
              ["pino",               "9.x",    "logging"],
            ].map(([n, v, k]) => (
              <div key={n} style={{ display: "flex", gap: 10, alignItems: "center", padding: "7px 0", borderTop: "1px solid var(--tan-2)" }}>
                <span style={{ fontFamily: "var(--mono, ui-monospace)", fontSize: 11.5, color: "var(--ink)", flex: 1 }}>{n}</span>
                <span style={{ fontFamily: "var(--mono, ui-monospace)", fontSize: 11, color: "var(--muted)" }}>{v}</span>
                <span style={{ fontSize: 10.5, color: "var(--muted-2)", textTransform: "uppercase", letterSpacing: 0.3, minWidth: 56, textAlign: "right" }}>{k}</span>
              </div>
            ))}
          </div>
        </div>

        <div style={{ padding: "0 18px 18px" }}>
          <div style={{ border: "1px solid var(--tan-2)", borderRadius: 10, padding: 16, background: "var(--cream-3)", marginBottom: 16 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 12 }}>
              <IconsT.Cloud s={14}/>
              <div style={{ fontSize: 12, fontWeight: 600, color: "var(--ink)", textTransform: "uppercase", letterSpacing: 0.4 }}>Infra & stack</div>
              <span className="tag" style={{ marginLeft: "auto" }}>provisioned by terraform on first deploy</span>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 0 }}>
              {[
                ["Runtime",          "Node 20 LTS on Vercel (BYOC: AWS Lambda via SST)"],
                ["Database",         "Postgres 16 on Neon (per-app branch, prod + preview)"],
                ["Queue",            "Inngest for background jobs + scheduled tasks"],
                ["Object storage",   "S3 bucket per app, prefixed meridia-{slug}-{env}"],
                ["Auth",             "Clerk SSO (Okta-backed), service-to-service via Vault tokens"],
                ["Secrets",          "Vault. No env-baked secrets. Rotation every 90d."],
                ["Observability",    "OpenTelemetry → Honeycomb + Sentry. Logs to Datadog."],
                ["CI / CD",          "GitHub Actions. Required checks: tests, audit, dep-scan."],
              ].map(([k, v], i) => (
                <div key={k} style={{
                  display: "grid", gridTemplateColumns: "120px 1fr", gap: 12,
                  padding: "9px 0",
                  borderTop: i < 2 ? "none" : "1px solid var(--tan-2)",
                  paddingLeft: i % 2 === 1 ? 16 : 0,
                  paddingRight: i % 2 === 0 ? 16 : 0,
                  borderRight: i % 2 === 0 ? "1px solid var(--tan-2)" : "none",
                }}>
                  <span style={{ fontSize: 11.5, color: "var(--muted-2)", textTransform: "uppercase", letterSpacing: 0.3, fontWeight: 600 }}>{k}</span>
                  <span style={{ fontSize: 12, color: "var(--ink)", lineHeight: 1.4 }}>{v}</span>
                </div>
              ))}
            </div>
          </div>

          <div style={{ border: "1px solid var(--tan-2)", borderRadius: 10, padding: 16, background: "var(--cream-3)" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 12 }}>
              <IconsT.Doc s={14}/>
              <div style={{ fontSize: 12, fontWeight: 600, color: "var(--ink)", textTransform: "uppercase", letterSpacing: 0.4 }}>Base prompts</div>
              <span className="tag" style={{ marginLeft: "auto" }}>shipped to every app's system prompt</span>
            </div>
            {[
              ["Stripe usage",        "All amounts in cents. Always idempotency-key mutating calls. Use webhooks for state changes, never polling."],
              ["Postgres safety",     "Read-only role for analytics. Always parameterize. Never run DDL from app code — migrations only via flyway."],
              ["LLM determinism",     "temperature=0 for any user-facing extraction. Use Sonnet for reasoning, Haiku for classification."],
              ["Error handling",      "Surface vendor errors as { code, vendor, retriable }. Never leak stack traces to the user."],
            ].map(([t, d]) => (
              <div key={t} style={{ padding: "10px 0", borderTop: "1px solid var(--tan-2)" }}>
                <div style={{ fontSize: 12.5, fontWeight: 500, color: "var(--ink)", marginBottom: 3 }}>{t}</div>
                <div style={{ fontSize: 12, color: "var(--muted)", lineHeight: 1.5 }}>{d}</div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Upcoming update */}
      <div className="card flush">
        <div className="card-head" style={{ padding: "16px 18px 14px", marginBottom: 0 }}>
          <div>
            <div className="card-title">Upcoming template update · v4.3.0</div>
            <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 3 }}>Auto-drafted from patterns Stoda observed across the fleet. Accept to roll into the next template release.</div>
          </div>
          <span className="sig" style={{ background: "var(--amber-bg)", color: "var(--amber)" }}>3 recommendations</span>
        </div>

        <div style={{ padding: "0 18px 18px", display: "flex", flexDirection: "column", gap: 12 }}>
          <RecCard
            id="r-stripe-meta"
            status={acceptedRecs["r-stripe-meta"]}
            onAccept={accept} onReject={reject}
            kind="Base prompt update"
            title="Add default instructions for Stripe API version & customer_type metadata"
            evidence="3 of 4 apps using Stripe (Quote Copilot, Invoice Matcher, Outbound Dialer) have hand-written this same guidance into their system prompts. Deal Desk Helper has it slightly wrong — references customer_type but uses 'pro' instead of the canonical 'enterprise'."
            diff={`+ Stripe calls must specify apiVersion: '2024-06-20'.
+ Differentiate billing logic on customer.metadata.customer_type
+ ('standard' | 'enterprise'); never on email domain.`}
            apps={["Quote Copilot", "Invoice Matcher", "Outbound Dialer", "Deal Desk Helper"]}
          />

          <RecCard
            id="r-sf-hs-lookup"
            status={acceptedRecs["r-sf-hs-lookup"]}
            onAccept={accept} onReject={reject}
            kind="New skill"
            title="Add customer-lookup skill: Salesforce ↔ Hubspot via salesforce_id metadata"
            evidence="2 apps (Quote Copilot, Onboarding Wizard) reimplemented this resolver independently with subtly different rounding on null SF IDs. r2 rec already flagged the implicit Salesforce → Postgres mapping as undocumented."
            diff={`+ skills/customer-lookup/index.ts
+   resolveCustomer({ salesforceId, hubspotId }):
+     1. If salesforceId present → SF is source of truth
+     2. Else lookup hubspot by hubspot_id → read sfdc_id metadata
+     3. Else throw NotFound (never silently create)`}
            apps={["Quote Copilot", "Onboarding Wizard"]}
            connection={{ name: "Salesforce REST", policy: "allowlisted" }}
          />

          <RecCard
            id="r-budget-default"
            status={acceptedRecs["r-budget-default"]}
            onAccept={accept} onReject={reject}
            kind="Default tightening"
            title="Lower default budget ceiling 80% → 70% for the first 30 days of an app's life"
            evidence="4 of last 6 budget overruns happened in the first 3 weeks while operators were still tuning prompts. Stricter early ceiling caught zero false positives in shadow mode (last 14 days)."
            diff={`  budget:
-   ceilingPct: 80
+   ceilingPct: 70  # first 30 days
+   ceilingPctMature: 80  # after firstSeen > 30d`}
            apps={["fleet-wide"]}
          />
        </div>

        <div style={{ padding: "14px 18px", borderTop: "1px solid var(--tan-2)", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 16, flexWrap: "wrap" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10, fontSize: 12, color: "var(--muted)" }}>
            <span style={{ width: 7, height: 7, borderRadius: "50%", background: optedOut ? "var(--muted-2)" : "var(--amber)", flexShrink: 0 }}/>
            {optedOut ? (
              <span>Auto-apply <em style={{ color: "var(--muted-2)" }}>paused</em>. v4.3.0 won't roll out unless you cut it manually.</span>
            ) : (
              <span>Pending recommendations <b style={{ color: "var(--ink)" }}>auto-accept and roll out in 7 days</b> unless you dismiss them. Apps re-template on next deploy.</span>
            )}
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            <button className="btn sm" onClick={() => setOptedOut(p => !p)}>{optedOut ? "Resume auto-apply" : "Pause auto-apply"}</button>
            <button className="btn sm accent">Cut v4.3.0 now</button>
          </div>
        </div>
      </div>
    </div>
  );
}

function RecCard({ id, status, onAccept, onReject, kind, title, evidence, diff, apps, connection }) {
  const accepted = status === true;
  const rejected = status === "rejected";
  return (
    <div style={{
      border: "1px solid " + (accepted ? "var(--green-border)" : rejected ? "var(--tan-2)" : "var(--tan-2)"),
      background: accepted ? "var(--green-bg)" : rejected ? "var(--cream-3)" : "var(--paper)",
      borderRadius: 10,
      opacity: rejected ? 0.55 : 1,
    }}>
      <div style={{ padding: "14px 16px", display: "flex", gap: 14, alignItems: "flex-start" }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6, flexWrap: "wrap" }}>
            <span style={{ fontSize: 10.5, color: "var(--muted-2)", textTransform: "uppercase", letterSpacing: 0.4, fontWeight: 600 }}>{kind}</span>
            {accepted && <PillT kind="ok">accepted</PillT>}
            {rejected && <PillT kind="warn">dismissed</PillT>}
          </div>
          <div style={{ fontSize: 14.5, fontWeight: 500, color: "var(--ink)", marginBottom: 8, lineHeight: 1.35 }}>{title}</div>
          <div style={{ fontSize: 12.5, color: "var(--muted)", lineHeight: 1.5, marginBottom: 10 }}>{evidence}</div>

          <pre style={{
            fontFamily: "var(--mono, ui-monospace)", fontSize: 11.5, lineHeight: 1.55,
            background: "var(--cream-3)", border: "1px solid var(--tan-2)", borderRadius: 6,
            padding: "10px 12px", margin: 0, overflow: "auto", color: "var(--ink)",
            whiteSpace: "pre-wrap",
          }}>
            {diff.split("\n").map((line, i) => {
              const isAdd = line.startsWith("+");
              const isRem = line.startsWith("-");
              return (
                <div key={i} style={{
                  color: isAdd ? "var(--green)" : isRem ? "var(--red)" : "var(--muted)",
                }}>{line}</div>
              );
            })}
          </pre>

          <div style={{ display: "flex", gap: 6, marginTop: 10, flexWrap: "wrap", alignItems: "center" }}>
            <span style={{ fontSize: 11, color: "var(--muted-2)" }}>Evidence from:</span>
            {apps.map(a => (
              <span key={a} className="tag" style={{ fontSize: 11 }}>{a}</span>
            ))}
            {connection && (
              <span style={{ marginLeft: 8, display: "inline-flex", alignItems: "center", gap: 5, fontSize: 11, color: "var(--muted)" }}>
                <span style={{ width: 5, height: 5, borderRadius: 3, background: "var(--green)" }}/>
                {connection.name} · {connection.policy}
              </span>
            )}
          </div>
        </div>

        {!accepted && !rejected && (
          <div style={{ display: "flex", flexDirection: "column", gap: 6, minWidth: 100 }}>
            <button className="btn sm accent" onClick={() => onAccept(id)}>Accept</button>
            <button className="btn sm" onClick={() => onReject(id)}>Dismiss</button>
          </div>
        )}
      </div>
    </div>
  );
}

window.TemplatePage = TemplatePage;
