/* ============================================================================
   DIVONCI WORLD — FOUNDRY CONTROL BOARD  (screens_foundry_control.jsx)
   ----------------------------------------------------------------------------
   The controlled change system that sits under Foundry:
     Packet  →  Change Request  →  Validation  →  Preview  →  Approval  →
     Deploy  →  Rollback
   Plus the agency handoff (Claude / Codex prompts). Every action is gated by
   DW.can(role, area) and agent boundaries via DW.agentCan, and writes an audit
   event through DW.mutate. Permission requests cover the five sensitive scopes.
   ========================================================================== */
const { useState: useStateFC } = React;

const FC_PERMS = [
  { key: "network",          label: "Network egress",   icon: "cloud",    desc: "Outbound network access" },
  { key: "scope_expansion",  label: "Scope expansion",  icon: "layers",   desc: "Work beyond the signed SOW" },
  { key: "external_api",     label: "External API",     icon: "plug",     desc: "Third-party API calls" },
  { key: "production_write", label: "Production write",  icon: "database", desc: "Writes to live production" },
  { key: "secrets",          label: "Secrets access",   icon: "lock",     desc: "Read a stored secret" },
];

/* ── one change request card ─────────────────────────────────────────────── */
function ChangeCard({ cr, auth }) {
  const runs = useResource("validation_runs", { eq: { changeRequestId: cr.id } });
  const previews = useResource("preview_deployments", { eq: { changeRequestId: cr.id } });
  const events = useResource("approval_events", { eq: { changeRequestId: cr.id } });
  const run = (runs.data || [])[0];
  const preview = (previews.data || [])[0];
  const canWrite = auth.can("foundry");
  const agentBound = DW.agentCan(cr.owner, "deploy");

  return (
    <Panel style={{ marginBottom: "var(--s-6)" }}>
      <div className="phead">
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <Led state={cr.state} />
          <div>
            <div style={{ fontFamily: "var(--font-display)", fontWeight: 600, fontSize: 15 }}>{cr.title}</div>
            <div className="client-mono" style={{ marginTop: 3 }}>{cr.id} · owner {DW.agent(cr.owner).name} · risk {cr.risk}</div>
          </div>
        </div>
        <span className="sbadge" style={{ color: DW.STATE_META[cr.state].c }}><span className="led" />{cr.status}</span>
      </div>
      <div className="pbody">
        <div style={{ fontSize: 13, color: "var(--ink-2)", lineHeight: 1.55, marginBottom: 16 }}>{cr.summary}</div>

        <div className="cols c-2" style={{ marginBottom: 16 }}>
          {/* validation */}
          <div>
            <div className="loop-k" style={{ marginBottom: 8 }}>Validation run</div>
            {runs.loading ? <LoadingState lines={2} label="Validating" /> : !run ? (
              <div className="client-mono" style={{ color: "var(--ink-4)" }}>No run yet</div>
            ) : (
              <div style={{ display: "grid", gap: 6 }}>
                {run.checks.map((c, i) => (
                  <div key={i} style={{ display: "flex", alignItems: "center", gap: 9, fontSize: 12.5 }}>
                    <Led state={c.state} size={7} /><span style={{ color: "var(--ink-2)" }}>{c.n}</span>
                    <span style={{ marginLeft: "auto", fontFamily: "var(--font-mono)", fontSize: 10, color: DW.STATE_META[c.state].c }}>{c.state === "standby" ? "queued" : c.state === "active" ? "running" : c.state === "clear" ? "pass" : "fail"}</span>
                  </div>
                ))}
              </div>
            )}
          </div>
          {/* preview */}
          <div>
            <div className="loop-k" style={{ marginBottom: 8 }}>Preview deployment</div>
            {previews.loading ? <LoadingState lines={2} label="Building preview" /> : !preview ? (
              <div className="client-mono" style={{ color: "var(--ink-4)" }}>No preview</div>
            ) : (
              <div style={{ border: "1px solid var(--hairline-2)", borderRadius: "var(--r-md)", padding: "12px 14px", background: "var(--graphite)" }}>
                <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                  <Led state={preview.state} size={7} />
                  <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, color: "var(--ink)" }}>{preview.url}</span>
                </div>
                <div className="client-mono" style={{ marginTop: 7 }}>{preview.status} · built {preview.built} · expires {preview.expires}</div>
              </div>
            )}
          </div>
        </div>

        {/* permission requests */}
        <div className="loop-k" style={{ marginBottom: 10 }}>Permission boundary · {DW.agent(cr.owner).name} {agentBound.gated ? "(" + agentBound.gated + ")" : ""}</div>
        <div className="perm-grid" style={{ marginBottom: 16 }}>
          {FC_PERMS.map((p) => {
            const requested = (cr.requestedPerms || []).includes(p.key);
            return (
              <div key={p.key} className={"perm-card " + (requested ? "requested" : "")}>
                <div className="ph"><Icon name={p.icon} style={{ width: 14, height: 14, color: requested ? "var(--state-caution)" : "var(--ink-3)" }} /> {p.label}</div>
                <div className="pd">{p.desc}</div>
                {requested ? (
                  <button className="btn" style={{ padding: "5px 10px", fontSize: 11 }} disabled={!canWrite}
                    title={canWrite ? "Grant this scope" : "Only commander+ can grant"}
                    onClick={() => DW.mutate("changeRequest.grantPermission", { id: cr.id, perm: p.key })}>
                    <Icon name="check" className="glyph" style={{ width: 12, height: 12 }} /> Grant
                  </button>
                ) : (
                  <button className="btn ghost" style={{ padding: "5px 10px", fontSize: 11 }} disabled={!canWrite}
                    onClick={() => DW.mutate("changeRequest.requestPermission", { id: cr.id, perm: p.key })}>
                    Request
                  </button>
                )}
              </div>
            );
          })}
        </div>

        {/* approval trail */}
        {events.data && events.data.length > 0 && (
          <div style={{ marginBottom: 16 }}>
            <div className="loop-k" style={{ marginBottom: 8 }}>Approval trail</div>
            {events.data.map((e) => (
              <div key={e.id} style={{ display: "flex", gap: 10, alignItems: "center", fontSize: 12.5, padding: "5px 0" }}>
                <span className="at" style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, color: "var(--ink-4)", width: 54 }}>{e.t}</span>
                <Led state={e.state} size={7} />
                <span style={{ color: "var(--ink-2)" }}><b style={{ color: "var(--ink)" }}>{e.actor}</b> {e.action}</span>
                <span style={{ color: "var(--ink-4)", marginLeft: "auto", fontSize: 11.5 }}>{e.note}</span>
              </div>
            ))}
          </div>
        )}

        {/* the gate: approve → deploy → rollback */}
        <div style={{ display: "flex", gap: 10, flexWrap: "wrap", paddingTop: 4 }}>
          <button className="btn primary" disabled={!canWrite || cr.status === "approved" || cr.status === "deployed"}
            onClick={() => DW.mutate("changeRequest.approve", { id: cr.id })}>
            <Icon name="check" className="glyph" style={{ width: 14, height: 14 }} /> Approve
          </button>
          <button className="btn gold" disabled={!canWrite || cr.status !== "approved"}
            title={cr.status !== "approved" ? "Approve first" : "Deploy to production"}
            onClick={() => DW.mutate("changeRequest.deploy", { id: cr.id })}>
            <Icon name="rocket" className="glyph" style={{ width: 14, height: 14 }} /> Deploy
          </button>
          <button className="btn danger" disabled={!canWrite || cr.status !== "deployed"}
            onClick={() => DW.mutate("changeRequest.rollback", { id: cr.id, reason: "Manual rollback from Foundry Control." })}>
            <Icon name="rollback" className="glyph" style={{ width: 14, height: 14 }} /> Rollback
          </button>
          {!canWrite && <span style={{ alignSelf: "center", fontFamily: "var(--font-mono)", fontSize: 10.5, color: "var(--ink-4)" }}>role “{auth.user.role}” is read-only in Foundry</span>}
        </div>
      </div>
    </Panel>
  );
}

/* ── packets lens ────────────────────────────────────────────────────────── */
function PacketsLens({ nav }) {
  const packets = useResource("foundry_packets", {});
  const gates = useResource("packet_gates", {});
  if (packets.loading) return <div style={{ padding: 18 }}><LoadingState lines={4} label="Loading packets" /></div>;
  if (packets.error) return <ErrorState error={packets.error} onRetry={packets.refetch} />;
  if (!packets.data.length) return <EmptyState icon="foundry" title="No packets staged" hint="Foundry packets prepared for build appear here." />;
  return (
    <div className="cols c-3">
      {packets.data.map((p) => {
        const pg = (gates.data || []).filter((g) => g.packetId === p.id);
        return (
          <Panel key={p.id} style={{ padding: "16px 18px" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
              <span className="sbadge" style={{ color: DW.STATE_META[p.state].c }}><span className="led" />{p.stage}</span>
              <Led state={p.state} />
            </div>
            <div style={{ fontFamily: "var(--font-display)", fontWeight: 600, fontSize: 15, marginBottom: 4 }}>{p.name}</div>
            <div className="client-mono" style={{ marginBottom: 12 }}>{p.openDecisions} open decision(s) · owner {DW.agent(p.owner).name}</div>
            <div className="healthbar" style={{ marginBottom: 10 }}><i style={{ width: Math.max(6, p.readiness) + "%", background: DW.STATE_META[p.state].c }} /></div>
            <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
              {pg.map((g) => (
                <span key={g.id} className="sbadge" style={{ fontSize: 9, color: DW.STATE_META[g.state].c }} title={g.label}>
                  <span className="led" />{g.kind}
                </span>
              ))}
            </div>
          </Panel>
        );
      })}
    </div>
  );
}

/* ── handoff lens (Claude / Codex prompts) ──────────────────────────────── */
/* ── appblueprints lens (preview before approval) ──────────────────────── */
function BlueprintsLens() {
  const auth = useAuth();
  const blueprints = useResource("app_blueprints", {});
  const packets = useResource("foundry_packets", {});
  if (blueprints.loading) return <div style={{ padding: 18 }}><LoadingState lines={3} label="Loading blueprints" /></div>;
  if (blueprints.error) return <ErrorState error={blueprints.error} onRetry={blueprints.refetch} />;
  if (!blueprints.data.length) return <EmptyState icon="layers" title="No blueprints yet" hint="Approved Foundry packets generate AppBlueprints here, ready to preview before build." />;
  return (
    <div className="cols c-2">
      {blueprints.data.map((b) => {
        const pkt = (packets.data || []).find((p) => p.id === b.packetId);
        return (
          <Panel key={b.id} style={{ padding: 0, overflow: "hidden" }}>
            <div className="phead">
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <Icon name="layers" style={{ width: 16, height: 16, color: "var(--violet-ink)" }} />
                <div><div style={{ fontWeight: 600, fontSize: 14 }}>{b.name}</div><div className="client-mono">{b.version} · {pkt ? pkt.name : "unlinked packet"}</div></div>
              </div>
              <span className="sbadge" style={{ color: DW.STATE_META[b.approved ? "clear" : b.state].c }}><span className="led" />{b.approved ? "approved" : "draft"}</span>
            </div>
            <div className="bp-preview">
              <span className="lbl">AppBlueprint preview · {b.surfaces} surfaces</span>
              <div className="bp-surfaces">{Array.from({ length: Math.min(b.surfaces, 9) }).map((_, i) => <i key={i} />)}</div>
            </div>
            <div className="pbody">
              <div className="bp-meta">
                {[["surfaces", b.surfaces], ["routes", b.routes], ["components", b.components], ["models", b.dataModels]].map(([k, n]) => (
                  <div className="c" key={k}><div className="n">{n}</div><div className="k">{k}</div></div>
                ))}
              </div>
              <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
                <button className="btn primary" disabled={!auth.can("foundry") || b.approved}
                  title={auth.can("foundry") ? "" : "Your role cannot approve blueprints"}
                  onClick={() => DW.mutate("update", { resource: "app_blueprints", id: b.id, patch: { approved: true, state: "clear" } })}>
                  <Icon name="check" className="glyph" style={{ width: 14, height: 14 }} /> {b.approved ? "Approved" : "Approve for build"}
                </button>
                <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--ink-4)" }}>{b.dataModels} models → src/lib/dw-api.ts</span>
              </div>
            </div>
          </Panel>
        );
      })}
    </div>
  );
}

function HandoffLens() {
  const blueprints = useResource("app_blueprints", {});
  if (blueprints.loading) return <div style={{ padding: 18 }}><LoadingState lines={3} label="Loading blueprints" /></div>;
  if (!blueprints.data.length) return <EmptyState icon="code" title="No blueprints to hand off" hint="Approved AppBlueprints generate Claude / Codex build prompts here." />;
  return (
    <div className="cols c-2">
      {blueprints.data.map((b) => (
        <Panel key={b.id} style={{ padding: 0, overflow: "hidden" }}>
          <div className="phead">
            <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
              <Icon name="code" style={{ width: 16, height: 16, color: "var(--violet-ink)" }} />
              <div><div style={{ fontWeight: 600, fontSize: 14 }}>{b.name}</div><div className="client-mono">{b.version} · {b.components} components · {b.dataModels} models</div></div>
            </div>
            <span className="sbadge" style={{ color: DW.STATE_META[b.state].c }}>{b.approved ? "approved" : "draft"}</span>
          </div>
          <pre style={{ margin: 0, padding: "14px 16px", fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--ink-2)", lineHeight: 1.6, whiteSpace: "pre-wrap", background: "var(--graphite)" }}>{`# Build handoff — ${b.name}
target: Vite + React + Supabase
surfaces: ${b.surfaces}   routes: ${b.routes}
data models: ${b.dataModels}  (see src/lib/dw-api.ts)

> All reads via DW.get(resource, params)
> All writes via DW.mutate(action, payload)
> Realtime via DW.subscribe(channel, cb)
> Swap mock→live at every // ⇄ SUPABASE marker`}</pre>
        </Panel>
      ))}
    </div>
  );
}

/* ── the board ───────────────────────────────────────────────────────────── */
const FC_HEADERS = {
  control:    { sub: "Foundry · seam-backed change records", title: "Change Control", meta: "The backend-ready governance layer behind Foundry Control: change requests, permission grants, validation runs, preview deploys and approval events — read and written through the API seam with a full audit trail." },
  packets:    { sub: "Foundry · build preparation", title: "Foundry Packets", meta: "Structured build packets and their gates, staged for build. Each packet carries a readiness score and any open decisions for Diego." },
  blueprints: { sub: "Foundry · app blueprints", title: "AppBlueprints", meta: "Generated application blueprints — surfaces, routes, components and data models — previewed and approved before they reach build." },
  handoff:    { sub: "Foundry · developer handoff", title: "Claude / Codex Handoff", meta: "Approved blueprints compiled into build prompts for Claude / Codex, pinned to the API seam contract in src/lib/dw-api.ts." },
};
const FC_FOOT = {
  control:    "⇄ This is the data/governance layer. Foundry Control (the console) drives the flow; here every change_request, permission grant, validation_run, preview_deployment and approval_event is the seam-backed record of it. Cycle the role pill to watch the gates engage.",
  packets:    "⇄ Reads: foundry_packets, packet_gates through DW.get. Gate state is colour-truth — green passed, amber pending, red failed.",
  blueprints: "⇄ Reads: app_blueprints, foundry_packets. ‘Approve for build’ writes through DW.mutate('update') → audit event → realtime.",
  handoff:    "⇄ Reads: app_blueprints. Each prompt targets the same DW.get / DW.mutate / DW.subscribe contract, so the build maps 1:1 onto the seam.",
};

function FoundryControlBoard({ nav, lens = "control" }) {
  const auth = useAuth();
  const [tab, setTab] = useStateFC(lens);
  React.useEffect(() => setTab(lens), [lens]);
  const changes = useResource("change_requests", {});
  const head = FC_HEADERS[tab] || FC_HEADERS.control;

  return (
    <div className="screen">
      <div className="screen-head">
        <div>
          <div className="title"><span className="sub">{head.sub}</span>{head.title}</div>
          <div className="meta">{head.meta}</div>
        </div>
        <div className="screen-actions">
          <div className="role-pill" onClick={() => { const order = ["sovereign", "commander", "operator", "viewer"]; const i = order.indexOf(auth.user.role); auth.signInAs(order[(i + 1) % order.length]); }}>
            <Led state={auth.user.role === "viewer" ? "standby" : "active"} size={7} /> {auth.user.role}
          </div>
        </div>
      </div>

      <div className="seg" style={{ marginBottom: "var(--s-6)" }} role="tablist">
        {[["control", "Change Control"], ["packets", "Packets"], ["blueprints", "AppBlueprints"], ["handoff", "Handoff"]].map(([k, l]) => (
          <button key={k} className={tab === k ? "on" : ""} data-accent="violet" role="tab" aria-selected={tab === k} onClick={() => setTab(k)}>{l}</button>
        ))}
      </div>

      {tab === "control" && (
        changes.loading ? <LoadingState lines={4} label="Loading change requests" />
        : changes.error ? <ErrorState error={changes.error} onRetry={changes.refetch} />
        : !changes.data.length ? <EmptyState icon="device" title="No open change requests" hint="Foundry packets raise change requests here for validation and approval." />
        : changes.data.map((cr) => <ChangeCard key={cr.id} cr={cr} auth={auth} />)
      )}
      {tab === "packets" && <PacketsLens nav={nav} />}
      {tab === "blueprints" && <BlueprintsLens />}
      {tab === "handoff" && <HandoffLens />}

      <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--ink-4)", marginTop: 14, lineHeight: 1.6 }}>{FC_FOOT[tab]}</div>
    </div>
  );
}

Object.assign(window, { FoundryControlBoard });
