/* ============================================================================
   DIVONCI WORLD — FOUNDRY CONTROL  (mobile PWA, embedded in the command OS)
   Approved admins request controlled code changes from Divonci.world, Telegram
   or Discord. Safe validation + deliberate deploy gates. The admin submits
   change requests — never edits raw code. Every action leaves an audit trail.
   ========================================================================== */
const { useState: useStateF, useEffect: useEffectF, useMemo: useMemoF } = React;

/* ---- status vocabulary (neon accent per status) ----------------------- */
const FS = {
  "Draft":             { s: "standby", c: "var(--state-standby)" },
  "Queued":            { s: "focus",   c: "var(--state-focus)" },
  "Generating Patch":  { s: "focus",   c: "var(--state-focus)" },
  "Patch Ready":       { s: "active",  c: "var(--state-active)" },
  "Validating":        { s: "caution", c: "var(--state-caution)", live: true },
  "Validation Failed": { s: "crisis",  c: "var(--state-crisis)" },
  "Preview Live":      { s: "clear",   c: "var(--state-clear)" },
  "Awaiting Approval": { s: "active",  c: "var(--gold-bright)", live: true },
  "Publishing":        { s: "focus",   c: "var(--state-focus)", live: true },
  "Published":         { s: "clear",   c: "var(--state-clear)" },
  "Rolled Back":       { s: "caution", c: "var(--state-caution)" },
  "Rejected":          { s: "crisis",  c: "var(--state-crisis)" },
};
const CHANGE_TYPES = ["Copy", "UI", "Data hook", "Bug fix", "Backend", "Deploy config"];
const PRIORITIES = ["Low", "Med", "High", "Urgent"];
const CHANNELS = { web: "Divonci.world", telegram: "Telegram", discord: "Discord" };

/* timeline stages, in order. each request carries `step` (furthest reached). */
const STAGES = ["Created", "Patch generated", "Validation running", "Preview deployed", "Approved", "Published"];

/* ---- seed change requests --------------------------------------------- */
const SEED = [
  { id: "CR-2041", title: "Tighten Council Comms scroll", target: "Divonci World", area: "Council Comms · right rail",
    type: "UI", priority: "High", env: "production", status: "Awaiting Approval", step: 3, channel: "telegram", cmd: "/cr 2041",
    author: "Diego", created: "09:14", agent: "VV",
    desc: "Right rail should scroll inside its own panel; the page must not move.",
    accept: "Page does not scroll · rail + chat each scroll internally · themed scrollbar.",
    diff: { files: 2, add: 41, del: 12 }, files: ["screens_ops.jsx", "styles/app.css"],
    preview: "cr2041.foundry.pages.dev",
    logs: [["ok", "build", "vite build — 4.2s, 0 errors"], ["ok", "browser", "page mounts, no console errors"], ["ok", "verify", "canvas overflow = false ✓"], ["ok", "shot", "screenshot captured"]] },

  { id: "CR-2039", title: "Fix slug preview overflow", target: "Divonci World", area: "Foundry packet · intake",
    type: "Bug fix", priority: "Med", env: "preview", status: "Validating", step: 2, channel: "discord", cmd: "/cr 2039",
    author: "Claws", created: "09:02", agent: "Optimus",
    desc: "Long slugs overflow the preview pill. Truncate with ellipsis.",
    accept: "Slug never overflows · ellipsis on overflow.",
    diff: { files: 1, add: 6, del: 1 }, files: ["styles/app.css"],
    preview: null,
    logs: [["ok", "build", "vite build — 3.9s, 0 errors"], ["run", "browser", "mounting preview…"], ["run", "verify", "checking overflow…"]] },

  { id: "CR-2044", title: "Edge deploy config — region pin", target: "Divonci World", area: "Deployments · edge",
    type: "Deploy config", priority: "High", env: "preview", status: "Validation Failed", step: 2, channel: "web", cmd: null,
    author: "BroDex", created: "08:51", agent: "BroDex",
    desc: "Pin the edge bundle to EU region for #A7F2.",
    accept: "Bundle pins EU · build green.",
    diff: { files: 1, add: 9, del: 2 }, files: ["wrangler.toml"],
    preview: null,
    logs: [["ok", "build", "vite build — 4.0s, 0 errors"], ["err", "browser", "TypeError: region 'eu-west' not in allowlist"], ["err", "verify", "validation halted — unsafe config"]] },

  { id: "CR-2045", title: "Foundry packet card badge", target: "Divonci World", area: "Projects · cards",
    type: "UI", priority: "Med", env: "preview", status: "Patch Ready", step: 1, channel: "web", cmd: null,
    author: "Diego", created: "08:33", agent: "VV",
    desc: "Draft packets need a dashed Draft · Packet badge.",
    accept: "Draft cards show badge · existing cards unchanged.",
    diff: { files: 2, add: 28, del: 0 }, files: ["app.jsx", "styles/app.css"],
    preview: null, logs: [["ok", "patch", "patch branch cr-2045 created"]] },

  { id: "CR-2046", title: "Risk console data hook", target: "Divonci World", area: "Risk Console",
    type: "Data hook", priority: "Med", env: "preview", status: "Queued", step: 0, channel: "telegram", cmd: "/cr 2046",
    author: "Nova", created: "08:20", agent: "BroDex",
    desc: "Wire the risk score feed to the live console.",
    accept: "Scores update live · no mock data.",
    diff: null, files: [], preview: null, logs: [] },

  { id: "CR-2030", title: "Update War Room banner copy", target: "Divonci World", area: "War Room · banner",
    type: "Copy", priority: "Low", env: "production", status: "Published", step: 5, channel: "web", cmd: null,
    author: "Viiera", created: "Jun 12", agent: "Claws", rollback: true,
    desc: "Refresh the mission banner wording.",
    accept: "Copy matches approved doctrine.",
    diff: { files: 1, add: 3, del: 3 }, files: ["screens_strategy.jsx"],
    preview: "cr2030.foundry.pages.dev", prod: "divonci.world",
    logs: [["ok", "build", "green"], ["ok", "verify", "passed"], ["ok", "deploy", "published to production"]] },

  { id: "CR-2028", title: "Rollback messaging experiment", target: "Divonci World", area: "Launch Messaging",
    type: "Copy", priority: "Low", env: "production", status: "Rolled Back", step: 5, channel: "web", cmd: null,
    author: "Diego", created: "Jun 11", agent: "Claws", rollback: true,
    desc: "Reverted the experimental hero line.",
    accept: "Prior copy restored.",
    diff: { files: 1, add: 2, del: 4 }, files: ["screens_strategy.jsx"],
    preview: "cr2028.foundry.pages.dev", prod: "divonci.world",
    logs: [["ok", "deploy", "rolled back to cr-2019"]] },
];

/* ---- deploy history --------------------------------------------------- */
const DEPLOYS_F = [
  { id: "dpl-91", cr: "CR-2041", env: "preview", url: "cr2041.foundry.pages.dev", state: "clear", t: "09:16", note: "Preview live" },
  { id: "dpl-90", cr: "CR-2039", env: "preview", url: "cr2039.foundry.pages.dev", state: "caution", t: "09:04", note: "Validating" },
  { id: "dpl-89", cr: "CR-2044", env: "preview", url: "—", state: "crisis", t: "08:53", note: "Validation failed" },
  { id: "dpl-88", cr: "CR-2030", env: "production", url: "divonci.world", state: "clear", t: "Jun 12 · 18:40", note: "Published" },
  { id: "dpl-87", cr: "CR-2028", env: "production", url: "divonci.world", state: "caution", t: "Jun 11 · 14:02", note: "Rolled back" },
];

/* ---- small atoms ------------------------------------------------------- */
function FChip({ status, sm }) {
  const m = FS[status] || FS.Draft;
  return (
    <span className={"fctl-chip" + (sm ? " sm" : "")} style={{ color: m.c, borderColor: "color-mix(in srgb, " + m.c + " 38%, transparent)", background: "color-mix(in srgb, " + m.c + " 14%, transparent)" }}>
      <span className={"fctl-dot" + (m.live ? " live" : "")} style={{ background: m.c, color: m.c }} />{status}
    </span>
  );
}
function ChannelTag({ ch, cmd }) {
  const icon = ch === "telegram" ? "comms" : ch === "discord" ? "council" : "globe";
  return <span className="fctl-chan"><Icon name={icon} className="glyph" style={{ width: 11, height: 11 }} />{cmd || CHANNELS[ch]}</span>;
}

/* ---- HQ / dashboard ---------------------------------------------------- */
function HQ({ reqs, open, go }) {
  const cards = fctlStats(reqs);
  const recent = reqs.slice(0, 5);
  return (
    <div className="fctl-pad">
      <div className="fctl-h"><div><b>HQ</b><span>Foundry Control · live</span></div><span className="fctl-pill"><span className="fctl-dot live" style={{ background: "var(--state-clear)", color: "var(--state-clear)" }} />{reqs.length} open</span></div>
      <div className="fctl-cards">
        {cards.map(c => (
          <button key={c.k} className="fctl-card focusable" onClick={() => c.k === "Ready to review" && go("reviews")}>
            <div className="fctl-card-top"><Icon name={c.icon} className="glyph" style={{ width: 14, height: 14, color: DW.STATE_META[c.s].c }} /><Led state={c.s} size={7} /></div>
            <div className="fctl-card-v" style={{ color: DW.STATE_META[c.s].c }}>{c.v}</div>
            <div className="fctl-card-k">{c.k}</div>
          </button>
        ))}
      </div>
      <div className="fctl-seclabel">Recent requests</div>
      <div className="fctl-list">
        {recent.map(r => <RequestRow key={r.id} r={r} onClick={() => open(r.id)} />)}
      </div>
    </div>
  );
}

function RequestRow({ r, onClick }) {
  return (
    <button className="fctl-row focusable" onClick={onClick}>
      <div className="fctl-row-main">
        <div className="fctl-row-id">{r.id} · <span>{r.type}</span></div>
        <div className="fctl-row-title">{r.title}</div>
        <div className="fctl-row-meta"><ChannelTag ch={r.channel} cmd={r.cmd} /><span className="fctl-area">{r.area}</span></div>
      </div>
      <div className="fctl-row-right"><FChip status={r.status} sm /><Icon name="chevron" className="glyph" style={{ width: 14, height: 14, color: "var(--ink-4)" }} /></div>
    </button>
  );
}

/* ---- New request form -------------------------------------------------- */
function NewRequest({ onSubmit, seed, project }) {
  const el = seed && seed.element;
  const [f, setF] = useStateF(() => ({ target: (project && project.name) || "Divonci World", area: (seed && seed.area) || "", type: (seed && seed.type) || "UI", desc: "", accept: "", priority: "Med", env: "preview" }));
  const set = (k, v) => setF(p => ({ ...p, [k]: v }));
  const ready = f.area.trim() && f.desc.trim();
  return (
    <div className="fctl-pad">
      <div className="fctl-h"><div><b>New request</b><span>{el ? "From a captured edit target" : "Submit a controlled change"}</span></div></div>

      {el && (
        <div className="fp-targetcard">
          <div className="fp-targetcard-head"><Icon name="eye" className="glyph" style={{ width: 13, height: 13 }} /><b>Edit target</b><span className="fp-targetcard-sel">{el.sel}</span></div>
          <div className="fp-targetcard-shot"><div className="fctl-shot-stripe" /><span className="fp-shotgrab-cap">{el.annotated ? "annotated screenshot" : "element capture"} · {(project && project.domain) || ""}</span></div>
          <div className="fp-targetcard-meta">
            <span><b>type</b> {el.type}</span><span><b>box</b> {el.box.w}×{el.box.h}</span>{el.file && <span><b>file</b> {el.file}</span>}
          </div>
        </div>
      )}

      <label className="fctl-field"><span className="fctl-label">Target app / site</span>
        {project
          ? <div className="fctl-input fctl-locked"><Icon name="globe" className="glyph" style={{ width: 13, height: 13 }} />{project.name}<span className="fctl-locktag">{project.domain}</span></div>
          : <select className="fctl-input" value={f.target} onChange={e => set("target", e.target.value)}>
              <option>Divonci World</option><option>Viiera Studio</option><option>Council Comms</option>
            </select>}
      </label>
      <label className="fctl-field"><span className="fctl-label">Area / tab / component</span>
        <input className="fctl-input" value={f.area} onChange={e => set("area", e.target.value)} placeholder="e.g. Council Comms · right rail" />
      </label>

      <div className="fctl-field"><span className="fctl-label">Change type</span>
        <div className="fctl-wrap">{CHANGE_TYPES.map(t => <button key={t} type="button" className={"fctl-tag" + (f.type === t ? " on" : "")} onClick={() => set("type", t)}>{t}</button>)}</div>
      </div>

      <label className="fctl-field"><span className="fctl-label">Request description</span>
        <textarea className="fctl-input" rows={3} value={f.desc} onChange={e => set("desc", e.target.value)} placeholder="Describe the outcome you want — not the code." />
      </label>
      <label className="fctl-field"><span className="fctl-label">Acceptance criteria</span>
        <textarea className="fctl-input" rows={2} value={f.accept} onChange={e => set("accept", e.target.value)} placeholder="How we'll know it's correct." />
      </label>

      <div className="fctl-field"><span className="fctl-label">Priority</span>
        <div className="fctl-wrap">{PRIORITIES.map(p => <button key={p} type="button" className={"fctl-tag" + (f.priority === p ? " on" : "")} onClick={() => set("priority", p)}>{p}</button>)}</div>
      </div>

      <div className="fctl-field"><span className="fctl-label">Attach screenshot</span>
        <div className="fctl-drop"><Icon name="evidence" className="glyph" style={{ width: 16, height: 16 }} /><span>Drop or tap to attach</span></div>
      </div>

      <div className="fctl-field"><span className="fctl-label">Environment</span>
        <div className="fctl-env">
          <button type="button" className={"fctl-envbtn" + (f.env === "preview" ? " on" : "")} onClick={() => set("env", "preview")}><b>Preview only</b><em>safe sandbox deploy</em></button>
          <button type="button" className={"fctl-envbtn gold" + (f.env === "production" ? " on" : "")} onClick={() => set("env", "production")}><b>Production after approval</b><em>requires deliberate publish</em></button>
        </div>
      </div>

      <button className="btn primary fctl-submit" disabled={!ready} onClick={() => onSubmit(f)}>
        <Icon name="bolt" className="glyph" style={{ width: 15, height: 15 }} /> Submit change request
      </button>
      <p className="fctl-fineprint">Foundry generates a patch against the GitHub source, validates it, and deploys a Cloudflare preview. Nothing reaches production without your approval.</p>
    </div>
  );
}

/* ---- Reviews ----------------------------------------------------------- */
function Reviews({ reqs, open }) {
  const review = reqs.filter(r => ["Preview Live", "Awaiting Approval", "Patch Ready"].includes(r.status));
  return (
    <div className="fctl-pad">
      <div className="fctl-h"><div><b>Reviews</b><span>{review.length} awaiting your call</span></div></div>
      {review.length === 0 ? <div className="fctl-empty"><Icon name="check" className="glyph" style={{ width: 18, height: 18 }} />Nothing waiting — all clear.</div> :
        <div className="fctl-list">{review.map(r => <RequestRow key={r.id} r={r} onClick={() => open(r.id)} />)}</div>}
    </div>
  );
}

/* ---- Deploys ----------------------------------------------------------- */
function Deploys({ open }) {
  return (
    <div className="fctl-pad">
      <div className="fctl-h"><div><b>Deploys</b><span>Preview &amp; production history</span></div></div>
      <div className="fctl-list">
        {DEPLOYS_F.map(d => (
          <div key={d.id} className="fctl-dep">
            <Led state={d.state} size={8} />
            <div className="fctl-dep-main">
              <div className="fctl-dep-top"><b>{d.cr}</b><span className={"fctl-envtag " + d.env}>{d.env}</span></div>
              <a className="fctl-url" onClick={e => e.preventDefault()} href={"https://" + d.url}>{d.url}</a>
            </div>
            <div className="fctl-dep-right"><span className="fctl-dep-note" style={{ color: DW.STATE_META[d.state].c }}>{d.note}</span><span className="fctl-dep-t">{d.t}</span></div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---- Settings ---------------------------------------------------------- */
function SettingsF() {
  const [reqApproval, setReqApproval] = useStateF(true);
  const admins = [
    { n: "Diego", r: "Sovereign · full", on: true }, { n: "Viiera", r: "Commander · approve + publish", on: true },
    { n: "BroDex", r: "Reviewer · validate", on: true }, { n: "Claws", r: "Requester · submit only", on: true },
  ];
  const services = [
    { n: "Supabase", d: "requests · logs · users", state: "clear", icon: "nexus" },
    { n: "GitHub", d: "source + patch branches", state: "clear", icon: "branch" },
    { n: "Cloudflare Worker", d: "API · Telegram · Discord", state: "clear", icon: "bolt" },
    { n: "Cloudflare Pages", d: "preview + production", state: "clear", icon: "rocket" },
  ];
  return (
    <div className="fctl-pad">
      <div className="fctl-h"><div><b>Settings</b><span>Permissions &amp; controls</span></div></div>

      <div className="fctl-seclabel">Deploy control</div>
      <button className={"fctl-switchrow" + (reqApproval ? " on" : "")} onClick={() => setReqApproval(v => !v)}>
        <div><b>Require approval for production</b><em>Production publish is always a deliberate confirmation.</em></div>
        <span className="fctl-switch" data-on={reqApproval}><i /></span>
      </button>

      <div className="fctl-seclabel">Admins &amp; roles</div>
      <div className="fctl-list">
        {admins.map(a => (
          <div key={a.n} className="fctl-admin">
            <div className="fctl-ava">{a.n[0]}</div>
            <div className="fctl-admin-main"><b>{a.n}</b><span>{a.r}</span></div>
            <Led state={a.on ? "clear" : "standby"} size={7} />
          </div>
        ))}
      </div>

      <div className="fctl-seclabel">Connected services</div>
      <div className="fctl-list">
        {services.map(s => (
          <div key={s.n} className="fctl-svc">
            <Icon name={s.icon} className="glyph" style={{ width: 15, height: 15, color: "var(--violet-ink)" }} />
            <div className="fctl-svc-main"><b>{s.n}</b><span>{s.d}</span></div>
            <span className="fctl-conn"><Led state={s.state} size={6} />connected</span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---- Request detail / review ------------------------------------------ */
function Detail({ r, back, act }) {
  const m = FS[r.status];
  const stepNow = r.status === "Validation Failed" ? r.step : r.step;
  const failed = r.status === "Validation Failed";
  return (
    <div className="fctl-detail">
      <div className="fctl-detail-head">
        <button className="fctl-back focusable" onClick={back}><Icon name="chevron" className="glyph" style={{ width: 16, height: 16, transform: "rotate(180deg)" }} /></button>
        <div><div className="fctl-detail-id">{r.id} · {r.type}</div><div className="fctl-detail-title">{r.title}</div></div>
        <FChip status={r.status} sm />
      </div>

      <div className="fctl-view comms-scroll">
        <div className="fctl-pad">
          <div className="fctl-meta-grid">
            <div><span>Target</span><b>{r.target}</b></div>
            <div><span>Area</span><b>{r.area}</b></div>
            <div><span>Priority</span><b>{r.priority}</b></div>
            <div><span>Source</span><b style={{ display: "inline-flex" }}><ChannelTag ch={r.channel} cmd={r.cmd} /></b></div>
          </div>

          <div className="fctl-block">
            <div className="fctl-block-l">Request</div>
            <p className="fctl-desc">{r.desc}</p>
            <div className="fctl-accept"><Icon name="check" className="glyph" style={{ width: 12, height: 12 }} />{r.accept}</div>
          </div>

          {r.element && (
            <div className="fctl-block">
              <div className="fctl-block-l">Selected element evidence</div>
              <div className="fp-targetcard mini">
                <div className="fp-targetcard-head"><Icon name="eye" className="glyph" style={{ width: 13, height: 13 }} /><span className="fp-targetcard-sel">{r.element.sel}</span></div>
                <div className="fp-targetcard-meta">
                  <span><b>type</b> {r.element.type}</span><span><b>box</b> {r.element.box.w}×{r.element.box.h}</span>{r.element.file && <span><b>file</b> {r.element.file}</span>}<span><b>context</b> {r.element.context}</span>
                </div>
              </div>
            </div>
          )}

          {/* status timeline */}
          <div className="fctl-seclabel">Status timeline</div>
          <div className="fctl-timeline">
            {STAGES.map((st, i) => {
              const done = i < stepNow || (i === stepNow && !FS[r.status].live && !failed && r.step > i);
              const isDone = i < r.step || (r.status === "Published" && i <= 5) || (r.status === "Rolled Back");
              const current = i === r.step && !isDone;
              const isFail = failed && i === r.step;
              const state = isFail ? "crisis" : isDone ? "clear" : current ? FS[r.status].s : "standby";
              return (
                <div key={st} className={"fctl-tl" + (isDone ? " done" : current ? " cur" : "")}>
                  <span className="fctl-tl-node" style={{ background: (isDone || current || isFail) ? DW.STATE_META[state].c : "var(--graphite)", borderColor: DW.STATE_META[state].c }}>
                    {isDone && <Icon name="check" className="glyph" style={{ width: 10, height: 10, color: "var(--obsidian)" }} />}
                    {isFail && <Icon name="close" className="glyph" style={{ width: 10, height: 10, color: "var(--obsidian)" }} />}
                  </span>
                  <span className="fctl-tl-l" style={{ color: isFail ? "var(--state-crisis)" : (isDone || current) ? "var(--ink)" : "var(--ink-4)" }}>{isFail ? "Validation failed" : st}{current && FS[r.status].live ? " …" : ""}</span>
                </div>
              );
            })}
          </div>

          {/* diff + files */}
          {r.diff && (
            <div className="fctl-block">
              <div className="fctl-block-l">Generated diff · {r.diff.files} file{r.diff.files > 1 ? "s" : ""}</div>
              <div className="fctl-diffstat"><span className="add">+{r.diff.add}</span><span className="del">−{r.diff.del}</span><span className="fctl-branch"><Icon name="branch" className="glyph" style={{ width: 11, height: 11 }} />patch/{r.id.toLowerCase()}</span></div>
              <div className="fctl-files">{r.files.map(fl => <div key={fl} className="fctl-file"><Icon name="evidence" className="glyph" style={{ width: 12, height: 12 }} />{fl}</div>)}</div>
            </div>
          )}

          {/* validation logs */}
          {r.logs.length > 0 && (
            <div className="fctl-block">
              <div className="fctl-block-l">Validation logs</div>
              <div className="fctl-term">
                {r.logs.map((l, i) => (
                  <div key={i} className={"fctl-logln " + l[0]}>
                    <span className="fctl-log-k">{l[0] === "ok" ? "✓" : l[0] === "err" ? "✕" : "…"} {l[1]}</span>
                    <span className="fctl-log-m">{l[2]}</span>
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* screenshot evidence */}
          <div className="fctl-block">
            <div className="fctl-block-l">Browser screenshot evidence</div>
            {r.preview || r.status === "Awaiting Approval" || r.status === "Published" ? (
              <div className="fctl-shot"><div className="fctl-shot-stripe" /><span className="fctl-shot-cap">verification capture · {r.id}</span></div>
            ) : <div className="fctl-shot pending"><span>awaiting validation…</span></div>}
          </div>

          {/* preview url */}
          {r.preview && (
            <div className="fctl-block">
              <div className="fctl-block-l">Preview</div>
              <div className="fctl-preview"><Icon name="globe" className="glyph" style={{ width: 14, height: 14, color: "var(--state-clear)" }} /><a className="fctl-url" href={"https://" + r.preview} onClick={e => e.preventDefault()}>{r.preview}</a><button className="fctl-share"><Icon name="arrow" className="glyph" style={{ width: 13, height: 13 }} /></button></div>
            </div>
          )}
        </div>
      </div>

      {/* action bar */}
      <div className="fctl-actbar">
        {failed ? (
          <>
            <button className="btn ghost" onClick={() => act(r.id, "revision")}>Request revision</button>
            <button className="btn danger" onClick={() => act(r.id, "reject")}>Reject</button>
          </>
        ) : r.status === "Published" || r.status === "Rolled Back" ? (
          <button className="btn ghost full" onClick={() => act(r.id, "rollback")}><Icon name="rollback" className="glyph" style={{ width: 14, height: 14 }} /> Roll back</button>
        ) : (
          <>
            <button className="btn ghost" onClick={() => act(r.id, "revision")}>Revision</button>
            <button className="btn danger" onClick={() => act(r.id, "reject")}>Reject</button>
            <button className="btn gold" onClick={() => act(r.id, "approve")} disabled={r.status !== "Awaiting Approval" && r.status !== "Preview Live"}><Icon name="lock" className="glyph" style={{ width: 13, height: 13 }} /> Approve publish</button>
          </>
        )}
      </div>
    </div>
  );
}

/* ---- dashboard stat helper (shared by mobile + desktop) --------------- */
function fctlStats(reqs) {
  const count = (pred) => reqs.filter(pred).length;
  return [
    { k: "Pending", v: count(r => ["Queued", "Generating Patch", "Patch Ready"].includes(r.status)), s: "focus", icon: "branch" },
    { k: "In validation", v: count(r => r.status === "Validating"), s: "caution", icon: "ops" },
    { k: "Ready to review", v: count(r => ["Preview Live", "Awaiting Approval"].includes(r.status)), s: "active", icon: "eye" },
    { k: "Published today", v: count(r => r.status === "Published"), s: "clear", icon: "check" },
    { k: "Failed validation", v: count(r => r.status === "Validation Failed"), s: "crisis", icon: "risk" },
    { k: "Rollbacks available", v: count(r => r.rollback), s: "standby", icon: "rollback" },
  ];
}

/* ======================================================================= *
   PERMISSION REQUESTS — agent asks for authority it does not hold:
   go online, touch files outside the requested scope, call an external API,
   or write to production. Foundry pauses and routes the ask to the admin.
 * ======================================================================= */
const PERM_KIND = {
  network:    { icon: "globe",  label: "network · go online",     c: "var(--state-focus)" },
  scope:      { icon: "branch", label: "scope expansion",         c: "var(--state-caution)" },
  external:   { icon: "bolt",   label: "external API call",        c: "var(--state-focus)" },
  production: { icon: "lock",   label: "production write",         c: "var(--gold-bright)" },
  secret:     { icon: "shield", label: "secret / credential",      c: "var(--state-crisis)" },
};
const PERMS_SEED = [
  { id: "perm-1", agent: "brodex", kind: "network", risk: "med", cr: "CR-2044",
    title: "Network access requested",
    detail: "BroDex needs to reach the external dependency registry to verify the origin of bundle #A7F2 before validation can continue. This is outside the agent's standing authorization.",
    scope: ["outbound HTTPS", "registry.npmjs.org", "read-only"] },
  { id: "perm-2", agent: "vv", kind: "scope", risk: "low", cr: "CR-2041",
    title: "Scope expansion requested",
    detail: "The patch for CR-2041 also needs to modify styles/app.css, which sits outside the requested area (Council Comms · right rail). VV is asking before widening the change.",
    scope: ["+1 file", "styles/app.css", "within repo"] },
  { id: "perm-3", agent: "optimus", kind: "external", risk: "med", cr: "CR-2046",
    title: "External API call requested",
    detail: "Optimus wants to call the live risk-score API to wire the Risk Console data hook. This reaches a third-party service beyond agent authority.",
    scope: ["risk-api.divonci.dev", "GET /scores", "rate-limited"] },
];

function RiskChip({ level }) {
  const m = { low: "clear", med: "caution", high: "crisis" }[level] || "standby";
  const c = DW.STATE_META[m].c;
  return <span className="fctl-riskchip" style={{ color: c, borderColor: "color-mix(in srgb, " + c + " 38%, transparent)" }}><span className="fctl-dot" style={{ background: c, color: c }} />{level} risk</span>;
}

/* layout-agnostic permission card — wrapped by a sheet (mobile) or modal (desktop) */
function PermissionCard({ perm, onResolve, onCancel }) {
  const a = DW.agent(perm.agent);
  const m = PERM_KIND[perm.kind];
  return (
    <div className="fctl-perm">
      <div className="fctl-perm-head">
        <span className="fctl-perm-ic" style={{ color: m.c, background: "color-mix(in srgb, " + m.c + " 15%, transparent)", borderColor: "color-mix(in srgb, " + m.c + " 40%, transparent)" }}><Icon name={m.icon} className="glyph" style={{ width: 20, height: 20 }} /></span>
        <div className="fctl-perm-headmain">
          <div className="fctl-perm-eyebrow">Outside agent authorization</div>
          <div className="fctl-perm-title">{perm.title}</div>
        </div>
        <RiskChip level={perm.risk} />
      </div>
      <div className="fctl-perm-agent">
        <img src={a.head} alt={a.name} style={{ borderColor: "color-mix(in srgb, " + a.ac + " 55%, transparent)" }} />
        <div><b style={{ color: a.ac }}>{a.name}</b><span>requests · {m.label}</span></div>
        <a className="fctl-perm-cr" href="#" onClick={e => e.preventDefault()}>{perm.cr}</a>
      </div>
      <p className="fctl-perm-detail">{perm.detail}</p>
      <div className="fctl-perm-scope">
        {perm.scope.map((s, i) => <span key={i} className="fctl-perm-scopechip">{s}</span>)}
      </div>
      <div className="fctl-perm-note"><Icon name="shield" className="glyph" style={{ width: 12, height: 12 }} /> Every decision is written to the audit trail. Granting does not auto-publish — deploy gates still apply.</div>
      <div className="fctl-perm-act">
        <button className="btn danger" onClick={() => onResolve(perm.id, "deny")}><Icon name="close" className="glyph" style={{ width: 13, height: 13 }} /> Deny</button>
        <button className="btn" onClick={() => onResolve(perm.id, "once")}>Grant once</button>
        <button className="btn primary" onClick={() => onResolve(perm.id, "always")}><Icon name="check" className="glyph" style={{ width: 13, height: 13 }} /> Always allow</button>
      </div>
    </div>
  );
}

/* confirm dialog copy (publish / reject / rollback) */
function confirmMeta(kind) {
  return {
    approve: { t: "Publish to production?", d: "This deploys the validated patch to the live site. Deliberate action — it cannot be silent.", btn: "Yes, publish live", cls: "gold", icon: "lock" },
    reject: { t: "Reject this request?", d: "The patch branch is discarded and the requester is notified.", btn: "Reject request", cls: "danger", icon: "close" },
    rollback: { t: "Roll back deploy?", d: "Production is reverted to the previous published version.", btn: "Roll back now", cls: "danger", icon: "rollback" },
  }[kind] || {};
}

const FCTL_NAVS = [["hq", "HQ", "globe"], ["inspect", "Inspect", "device"], ["new", "New", "plus"], ["reviews", "Reviews", "eye"], ["deploys", "Deploys", "rocket"], ["settings", "Settings", "settings"]];

/* ---- MOBILE shell (phone + operational context) ----------------------- */
function FctlPhone(p) {
  const cm = p.confirm ? confirmMeta(p.confirm.kind) : {};
  const permObj = p.perms.find(x => x.id === p.permSel);
  return (
    <div className="fctl-stage">
      <div className="fctl-phone">
        <div className="fctl-bezel">
          <div className="fctl-statusbar"><span>9:41</span><span className="fctl-notch" /><span className="fctl-sbicons"><Led state="clear" size={5} /> Foundry</span></div>
          <div className="fctl-app">
            {p.sel && p.selReq ? (
              <Detail r={p.selReq} back={p.back} act={p.act} />
            ) : (
              <>
                <div className="fp-mobbar"><window.ProjectSwitcher project={p.project} reqs={p.allReqs} onPick={p.pickProject} onAll={() => p.pickProject(null)} /></div>
                {p.perms.length > 0 && (
                  <div className="fctl-permbar">
                    <button className="fctl-permbanner focusable" onClick={() => p.openPerm(p.perms[0].id)}>
                      <span className="fctl-permbanner-ic"><Icon name="shield" className="glyph" style={{ width: 16, height: 16 }} /></span>
                      <div className="fctl-permbanner-main"><b>{p.perms.length} authorization{p.perms.length > 1 ? "s" : ""} pending</b><em>An agent needs permission beyond its authority</em></div>
                      <Icon name="chevron" className="glyph" style={{ width: 15, height: 15, color: "var(--gold-bright)" }} />
                    </button>
                  </div>
                )}
                <div className="fctl-view comms-scroll">
                  {p.tab === "hq" && <HQ reqs={p.reqs} open={p.open} go={p.go} />}
                  {p.tab === "inspect" && <window.MobileAnnotate project={p.project} onCreateCR={p.createCR} />}
                  {p.tab === "new" && <NewRequest onSubmit={p.submit} seed={p.seed} project={p.project} />}
                  {p.tab === "reviews" && <Reviews reqs={p.reqs} open={p.open} />}
                  {p.tab === "deploys" && <Deploys open={p.open} />}
                  {p.tab === "settings" && <SettingsF />}
                </div>
                <nav className="fctl-nav">
                  {FCTL_NAVS.map(([id, lbl, ic]) => (
                    <button key={id} className={"fctl-navbtn" + (p.tab === id ? " on" : "")} onClick={() => p.setTab(id)}>
                      <Icon name={ic} className="glyph" style={{ width: 19, height: 19 }} /><span>{lbl}</span>
                    </button>
                  ))}
                </nav>
              </>
            )}

            {/* permission request sheet */}
            {permObj && (
              <div className="fctl-sheet-root">
                <div className="fctl-sheet-bd" onClick={() => p.setPermSel(null)} />
                <div className="fctl-sheet wide"><PermissionCard perm={permObj} onResolve={p.resolvePerm} /></div>
              </div>
            )}

            {/* confirm sheet */}
            {p.confirm && (
              <div className="fctl-sheet-root">
                <div className="fctl-sheet-bd" onClick={() => p.setConfirm(null)} />
                <div className="fctl-sheet">
                  <div className={"fctl-sheet-ic " + cm.cls}><Icon name={cm.icon} className="glyph" style={{ width: 20, height: 20 }} /></div>
                  <div className="fctl-sheet-t">{cm.t}</div>
                  <div className="fctl-sheet-d">{cm.d}</div>
                  <div className="fctl-sheet-act">
                    <button className="btn ghost" onClick={() => p.setConfirm(null)}>Cancel</button>
                    <button className={"btn " + cm.cls} onClick={() => p.applyAct(p.confirm.id, p.confirm.kind)}>{cm.btn}</button>
                  </div>
                </div>
              </div>
            )}

            {p.toast && <div className="fctl-toast"><Led state="clear" size={6} />{p.toast}</div>}
          </div>
        </div>
      </div>

      {/* operational context */}
      <div className="fctl-context comms-scroll">
        <Panel className="tight">
          <PHead icon="branch" eyebrow="Change pipeline" title="How a request flows" />
          <div className="pbody fctl-flow">
            {[["Admin submits", "globe", "web · Telegram · Discord"], ["Stored in Supabase", "nexus", "request + audit row"], ["Agent patches GitHub", "branch", "patch branch, no direct edits"], ["Validation runs", "ops", "build · browser · screenshot"], ["Cloudflare preview", "rocket", "shareable preview URL"], ["Admin approves", "lock", "deliberate production publish"], ["Published + logged", "check", "deploy URL in audit trail"]].map(([t, ic, d], i) => (
              <div key={i} className="fctl-flowstep">
                <span className="fctl-flow-n">{i + 1}</span>
                <Icon name={ic} className="glyph" style={{ width: 15, height: 15, color: "var(--violet-ink)" }} />
                <div><b>{t}</b><em>{d}</em></div>
              </div>
            ))}
          </div>
        </Panel>

        <Panel className="tight">
          <PHead icon="shield" eyebrow="Authorization model" />
          <div className="pbody fctl-channels">
            <p className="fctl-ctx-note">Agents act inside fixed authority. To <b>go online</b>, touch files outside the requested area, call an external API, or write to production, the agent must request permission — surfaced here for a human decision.</p>
            {Object.keys(PERM_KIND).map(k => (
              <div key={k} className="fctl-chrow"><Icon name={PERM_KIND[k].icon} className="glyph" style={{ width: 14, height: 14, color: PERM_KIND[k].c }} /><b style={{ textTransform: "capitalize" }}>{k}</b><span>{PERM_KIND[k].label}</span></div>
            ))}
          </div>
        </Panel>

        <Panel className="tight">
          <PHead icon="filter" eyebrow="Status vocabulary" />
          <div className="pbody fctl-legend">
            {Object.keys(FS).map(k => (
              <span key={k} className="fctl-legchip" style={{ color: FS[k].c, borderColor: "color-mix(in srgb, " + FS[k].c + " 34%, transparent)" }}>
                <span className="fctl-dot" style={{ background: FS[k].c, color: FS[k].c }} />{k}
              </span>
            ))}
          </div>
        </Panel>
      </div>
    </div>
  );
}

/* ---- state holder + layout router ------------------------------------- */
const FCTL_KEY = "dw_fctl_state_v1";
function loadFctl() { try { return JSON.parse(localStorage.getItem(FCTL_KEY)) || {}; } catch (e) { return {}; } }
function saveFctl(s) { try { localStorage.setItem(FCTL_KEY, JSON.stringify(s)); } catch (e) {} }

function FoundryControlScreen({ nav }) {
  const init = loadFctl();
  const [view, setView] = useStateF(init.view || "desktop");
  const [reqs, setReqs] = useStateF(() => [...SEED.map(r => ({ ...r, project: r.project || "divonci" })), ...(window.EXTRA_SEED || [])]);
  const [perms, setPerms] = useStateF(PERMS_SEED);
  const [project, setProject] = useStateF(init.project || null); // selected project id or null (selector)
  const [seed, setSeed] = useStateF(null);                       // CR draft seed captured from Inspect
  const [tab, setTab] = useStateF(init.tab || "hq");
  const [sel, setSel] = useStateF(init.sel || null);
  const [permSel, setPermSel] = useStateF(null);   // permission id being prompted
  const [newOpen, setNewOpen] = useStateF(false);  // desktop new-request modal
  const [confirm, setConfirm] = useStateF(null);   // { id, kind }
  const [toast, setToast] = useStateF(null);

  useEffectF(() => { saveFctl({ view, tab, sel, project }); }, [view, tab, sel, project]);
  useEffectF(() => { if (!toast) return; const t = setTimeout(() => setToast(null), 2400); return () => clearTimeout(t); }, [toast]);

  const open = (id) => setSel(id);
  const back = () => setSel(null);
  const go = (t) => { setSel(null); setTab(t); };
  const openPerm = (id) => setPermSel(id);
  const projObj = project ? window.fproj(project) : null;
  const scopedReqs = project ? reqs.filter(r => r.project === project) : reqs;
  const selReq = reqs.find(r => r.id === sel);
  function pickProject(pid) { setProject(pid); setSel(null); setTab("hq"); }
  function createCRfromInspect(picked) {
    setSeed(window.elementToSeed(picked, projObj));
    if (view === "desktop") setNewOpen(true); else setTab("new");
  }

  function submit(f) {
    const id = "CR-" + (2047 + reqs.filter(r => r.id.startsWith("CR-20")).length);
    const nr = { id, title: f.desc.slice(0, 42) || "New change request", target: f.target, area: f.area || "—",
      type: f.type, priority: f.priority, env: f.env, status: "Queued", step: 0, channel: "web", cmd: null,
      project: project || "divonci", element: (seed && seed.element) || null,
      author: "Diego", created: "now", agent: "VV", desc: f.desc, accept: f.accept || "—",
      diff: null, files: [], preview: null, logs: [] };
    setReqs(r => [nr, ...r]);
    setTab("hq"); setNewOpen(false); setSeed(null); setToast(id + " queued · patch generating");
  }

  function act(id, kind) {
    if (kind === "approve" || kind === "reject" || kind === "rollback") { setConfirm({ id, kind }); return; }
    if (kind === "revision") { applyAct(id, kind); }
  }
  function applyAct(id, kind) {
    setReqs(rs => rs.map(r => {
      if (r.id !== id) return r;
      if (kind === "approve") return { ...r, status: "Published", step: 5, rollback: true, prod: "divonci.world", logs: [...r.logs, ["ok", "deploy", "published to production"]] };
      if (kind === "reject") return { ...r, status: "Rejected" };
      if (kind === "rollback") return { ...r, status: "Rolled Back", logs: [...r.logs, ["ok", "deploy", "rolled back"]] };
      if (kind === "revision") return { ...r, status: "Queued", step: 0, logs: [["ok", "patch", "revision requested — regenerating"]] };
      return r;
    }));
    const msg = { approve: "Published to production", reject: "Request rejected", rollback: "Rolled back", revision: "Revision requested" }[kind];
    setConfirm(null); setToast(msg);
    if (kind === "approve" || kind === "rollback") back();
  }

  function resolvePerm(id, decision) {
    const perm = perms.find(x => x.id === id);
    setPerms(ps => ps.filter(x => x.id !== id));
    setPermSel(null);
    if (perm) {
      const a = DW.agent(perm.agent).name;
      const verb = decision === "deny" ? "denied" : decision === "always" ? "always-allowed" : "granted once";
      setToast(a + " · " + PERM_KIND[perm.kind].label.split(" ·")[0] + " " + verb);
      // a granted network ask unblocks the failed validation it was holding
      if (decision !== "deny" && perm.kind === "network") {
        setReqs(rs => rs.map(r => r.id === perm.cr ? { ...r, status: "Validating", logs: [...r.logs, ["ok", "auth", "network granted — re-running validation"]] } : r));
      }
    }
  }

  const ctx = { reqs: scopedReqs, allReqs: reqs, project: projObj, pickProject, createCR: createCRfromInspect, seed,
    tab, setTab, sel, selReq, open, back, go, submit, act, applyAct,
    confirm, setConfirm, toast, perms, permSel, setPermSel, openPerm, resolvePerm,
    newOpen, setNewOpen, nav };
  const Desk = window.FctlDesktop;

  return (
    <div className="screen fctl-screen-wrap">
      <div className="screen-head">
        <div><div className="title"><span className="sub">Execution · PWA + Console</span>Foundry Control</div>
          <div className="meta">Approved admins request controlled code changes from Divonci.world, Telegram, or Discord — with safe validation and deliberate deploy gates.</div></div>
        <div className="screen-actions">
          {project && perms.length > 0 && <button className="fctl-permpill" onClick={() => { setSel(null); openPerm(perms[0].id); }}><Icon name="shield" className="glyph" style={{ width: 13, height: 13 }} />{perms.length} pending</button>}
          <span className="sbadge" style={{ color: "var(--state-clear)" }}><Led state="clear" size={7} /> Worker online</span>
          {project && (
            <div className="seg fctl-viewseg">
              <button className={view === "desktop" ? "on" : ""} onClick={() => setView("desktop")}>Desktop</button>
              <button className={view === "mobile" ? "on" : ""} onClick={() => setView("mobile")}>Mobile</button>
            </div>
          )}
        </div>
      </div>

      {!project ? <window.ProjectSelector reqs={reqs} onPick={pickProject} />
        : view === "mobile" ? <FctlPhone {...ctx} /> : (Desk ? <Desk {...ctx} /> : null)}
    </div>
  );
}

Object.assign(window, {
  FoundryControlScreen, FctlPhone, fctlStats,
  FChip, ChannelTag, RequestRow, NewRequest, Detail, Deploys, SettingsF, Reviews, HQ,
  FS, DEPLOYS_F, PERM_KIND, PermissionCard, RiskChip, confirmMeta, FCTL_NAVS,
});
