/* OpenMAO Operator Console — interactive recreation.
   Structure & behavior mirror ts/src/api/server.ts (tabs, token, approve/reject,
   world model, events, traces), rendered in the OpenMAO design system. */
const { useState, useEffect, useRef } = React;
const D = window.OM_DATA;

const NAV = [
  { cap: "Govern" },
  { id: "world", label: "World", icon: "globe" },
  { id: "runs", label: "Runs", icon: "play" },
  { id: "work", label: "Work", icon: "list-checks" },
  { id: "agents", label: "Agents", icon: "bot" },
  { cap: "Review" },
  { id: "approvals", label: "Approvals", icon: "shield-check" },
  { id: "promotions", label: "Promotions", icon: "arrow-up-circle" },
  { id: "learning", label: "Learning", icon: "git-branch" },
  { cap: "Record" },
  { id: "memory", label: "Memory", icon: "database" },
  { id: "capabilities", label: "Capabilities", icon: "blocks" },
  { id: "capabilityCalls", label: "Capability Calls", icon: "arrow-right-left" },
  { id: "events", label: "Events", icon: "activity" },
  { id: "traces", label: "Traces", icon: "git-commit-horizontal" },
];

const TITLES = {
  world: "World", runs: "Runs", work: "Work", agents: "Agents", approvals: "Approvals",
  promotions: "Promotions", learning: "Learning", memory: "Memory", capabilities: "Capabilities",
  capabilityCalls: "Capability Calls", events: "Events", traces: "Traces",
};

function Panel({ title, action, children, flush }) {
  return (
    <div className="panel">
      {title && (
        <div className="panel-head">
          <span className="ph-title">{title}</span>
          {action}
        </div>
      )}
      <div className={flush ? "" : "panel-body"}>{children}</div>
    </div>
  );
}

function ConsoleApp() {
  const [theme, setTheme] = useState("light");
  const [view, setView] = useState("world");
  const [runStatus, setRunStatus] = useState("suspended_approval");
  const [approval, setApproval] = useState("pending"); // pending|approved|rejected
  const [promo, setPromo] = useState("pending");
  const [learn, setLearn] = useState({ ocp_01: "proposed", ocp_02: "approved" });
  const [toast, setToast] = useState("");
  const toastTimer = useRef(null);

  useEffect(() => {
    document.documentElement.setAttribute("data-theme", theme);
  }, [theme]);

  function flash(msg) {
    setToast(msg);
    clearTimeout(toastTimer.current);
    toastTimer.current = setTimeout(() => setToast(""), 2200);
  }

  function approveGate() {
    setApproval("approved"); setRunStatus("completed"); setPromo("ratified");
    flash("approval.approved → run resumed → memory promoted");
  }
  function rejectGate() {
    setApproval("rejected"); setRunStatus("failed"); setPromo("rejected");
    flash("approval.rejected → run failed (reversible)");
  }

  const events = D.baseEvents.concat(runStatus === "completed" ? D.approvedEvents : []);
  const pendingApprovals = approval === "pending"
    ? [{ id: "approval_1111…", action: "memory.promote", status: "pending", on_approve: "resume_run", on_reject: "fail_run" }]
    : [];

  return (
    <div className="console">
      <header className="con-header">
        <div className="con-brand">
          <img src={theme === "dark" ? "/assets/openmao-mark-transparent.png" : "/assets/openmao-mark.png"} alt="" />
          <span className="name">OpenMAO Console</span>
        </div>
        <div className="con-ws">
          <span className="wsname">{D.WS}</span>
          <AutonomyPill level={D.org.autonomy_level} />
        </div>
        <div className="con-toolbar">
          <input className="input" type="password" defaultValue="••••••••••••••••" aria-label="Operator token" />
          <Btn size="sm" onClick={() => flash("refreshed world model")}>Refresh</Btn>
          <Btn size="sm" onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>
            <Icon name={theme === "dark" ? "sun" : "moon"} size={15} />
          </Btn>
        </div>
      </header>

      <div className="con-main">
        <nav className="con-nav" aria-label="Console views">
          {NAV.map((n, i) =>
            n.cap ? (
              <div key={"c" + i} className="navcap">{n.cap}</div>
            ) : (
              <button key={n.id} className={"navbtn" + (view === n.id ? " active" : "")} aria-pressed={view === n.id} onClick={() => setView(n.id)}>
                <Icon name={n.icon} size={16} cls="ico" />{n.label}
              </button>
            )
          )}
        </nav>

        <section className="con-section">
          <div className="con-titlerow">
            <div>
              <h2>{TITLES[view]}</h2>
              <div className="sub">{D.WS}</div>
            </div>
            {view === "world" && (
              <div style={{ display: "flex", gap: 8 }}>
                <Btn variant="primary" size="sm" onClick={() => { setRunStatus("suspended_approval"); setApproval("pending"); setPromo("pending"); flash("demo started → suspended at approval gate"); }}>Run demo</Btn>
              </div>
            )}
          </div>

          {view === "world" && <WorldView runStatus={runStatus} approval={approval} />}
          {view === "runs" && <RunsView runStatus={runStatus} />}
          {view === "work" && <WorkView />}
          {view === "agents" && <AgentsView />}
          {view === "approvals" && <ApprovalsView pending={pendingApprovals} approval={approval} onApprove={approveGate} onReject={rejectGate} />}
          {view === "promotions" && <PromotionsView promo={promo} />}
          {view === "learning" && <LearningView learn={learn} setLearn={setLearn} flash={flash} />}
          {view === "memory" && <MemoryView />}
          {view === "capabilities" && <CapabilitiesView />}
          {view === "capabilityCalls" && <CapabilityCallsView />}
          {view === "events" && <EventsView events={events} />}
          {view === "traces" && <TracesView />}
        </section>
      </div>

      <div className={"toast" + (toast ? " show" : "")}>{toast}</div>
    </div>
  );
}

/* ---------------- Views ---------------- */
function WorldView({ runStatus, approval }) {
  const w = D.worldPending;
  return (
    <div>
      <div className={"gate-banner" + (runStatus === "completed" ? " ok" : "")}>
        <Icon name={runStatus === "completed" ? "check-circle-2" : "pause-circle"} size={16} />
        {runStatus === "completed"
          ? "Run completed. Memory promoted to collective. Track record updated."
          : runStatus === "failed"
          ? "Run failed at the gate — reversible. Re-run the demo to retry."
          : "Run suspended at a governance gate. One approval pending in Approvals."}
      </div>
      <div className="statgrid">
        <div className="stat"><div className="sv">{runStatus}</div><div className="sk">latest_run_status</div></div>
        <div className="stat"><div className="sv">{approval === "pending" ? 1 : 0}</div><div className="sk">pending_approvals</div></div>
        <div className="stat"><div className="sv">{w.active_work}</div><div className="sk">active_work</div></div>
        <div className="stat"><div className="sv">{w.open_org_change_proposals.length}</div><div className="sk">open_proposals</div></div>
      </div>
      <Panel title="World model snapshot" action={<span className="tag">cache_only</span>}>
        <div className="kvlist">
          <div className="kvrow"><span className="kk">autonomy_level</span><span className="vv"><AutonomyPill level={w.autonomy_level} /></span></div>
          <div className="kvrow"><span className="kk">blockers</span><span className="vv">{w.blockers.map((b, i) => <div key={i}>{b}</div>)}</span></div>
          <div className="kvrow"><span className="kk">pending_reviews</span><span className="vv" style={{ fontFamily: "var(--font-mono)", fontSize: 12 }}>{w.pending_reviews.join(", ")}</span></div>
          <div className="kvrow"><span className="kk">learning_signals</span><span className="vv" style={{ fontFamily: "var(--font-mono)", fontSize: 12 }}>{w.learning_signals.join("  ·  ")}</span></div>
          <div className="kvrow"><span className="kk">capability_gaps</span><span className="vv" style={{ fontFamily: "var(--font-mono)", fontSize: 12 }}>{w.capability_gaps.join(", ")}</span></div>
        </div>
      </Panel>
    </div>
  );
}

function RunsView({ runStatus }) {
  return (
    <Panel flush>
      <table className="table">
        <thead><tr><th>ID</th><th>Status</th><th>Active node</th><th>Suspended approval</th></tr></thead>
        <tbody>
          <tr>
            <td className="mono">run_99999…</td>
            <td><StatusBadge status={runStatus} /></td>
            <td className="mono">{runStatus === "completed" ? "—" : "gate.approval"}</td>
            <td className="mono">{runStatus === "suspended_approval" ? "approval_1111…" : "—"}</td>
          </tr>
        </tbody>
      </table>
    </Panel>
  );
}

function WorkView() {
  return (
    <Panel flush>
      <table className="table">
        <thead><tr><th style={{ width: 100 }}>ID</th><th>Title</th><th style={{ width: 130 }}>Owner</th><th style={{ width: 90 }}>Risk</th><th style={{ width: 130 }}>Status</th></tr></thead>
        <tbody>
          {D.work.map((w) => (
            <tr key={w.id}>
              <td className="mono">{w.id}</td>
              <td>{w.title}</td>
              <td className="mono">{w.owner.replace("agent_", "")}</td>
              <td><RiskTag level={w.risk_level} /></td>
              <td><StatusBadge status={w.status} /></td>
            </tr>
          ))}
        </tbody>
      </table>
    </Panel>
  );
}

function AgentsView() {
  return (
    <Panel flush>
      <table className="table">
        <thead><tr><th>ID</th><th>Identity</th><th>Role</th><th>Model</th><th style={{ width: 110 }}>Status</th></tr></thead>
        <tbody>
          {D.agents.map((a) => (
            <tr key={a.id}>
              <td className="mono">{a.id}</td>
              <td>{a.identity}</td>
              <td className="mono">{a.role_id.replace("role_", "")}</td>
              <td className="mono">{a.model_binding}</td>
              <td><StatusBadge status={a.status} /></td>
            </tr>
          ))}
        </tbody>
      </table>
    </Panel>
  );
}

function ApprovalsView({ pending, approval, onApprove, onReject }) {
  if (pending.length === 0) {
    return (
      <Panel>
        <div className="emptyrow">
          No pending approvals. Last gate was <strong style={{ color: approval === "approved" ? "var(--state-success-fg)" : "var(--state-danger-fg)" }}>{approval}</strong>.
        </div>
      </Panel>
    );
  }
  const a = pending[0];
  return (
    <div className="panel">
      <div className="panel-body" style={{ display: "flex", flexDirection: "column", gap: 14 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 12 }}>
          <div>
            <div style={{ fontSize: 15, fontWeight: 600 }}>Promote memory to collective</div>
            <div className="mono" style={{ fontSize: 11, color: "var(--fg-3)", marginTop: 3 }}>approval_11111111111111111111111111111111</div>
          </div>
          <StatusBadge status="pending" />
        </div>
        <div className="rationale" style={{ borderLeft: "2px solid var(--accent-weak-line)", paddingLeft: 12 }}>
          Run produced a reusable onboarding brief. Promotion writes the entry to organizational memory after approval. Action is reversible.
        </div>
        <div className="kvlist">
          <div className="kvrow"><span className="kk">action</span><span className="vv mono" style={{ fontFamily: "var(--font-mono)", fontSize: 12 }}>{a.action}</span></div>
          <div className="kvrow"><span className="kk">on_approve</span><span className="vv" style={{ fontFamily: "var(--font-mono)", fontSize: 12 }}>{a.on_approve}</span></div>
          <div className="kvrow"><span className="kk">on_reject</span><span className="vv" style={{ fontFamily: "var(--font-mono)", fontSize: 12 }}>{a.on_reject}</span></div>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <Btn variant="primary" onClick={onApprove}>Approve</Btn>
          <Btn variant="danger" onClick={onReject}>Reject</Btn>
        </div>
      </div>
    </div>
  );
}

function PromotionsView({ promo }) {
  const p = D.promotionPending;
  return (
    <Panel flush>
      <table className="table">
        <thead><tr><th>ID</th><th>Proposed by</th><th>Source entry</th><th style={{ width: 80 }}>Corrob.</th><th style={{ width: 120 }}>Status</th></tr></thead>
        <tbody>
          <tr>
            <td className="mono">{p.id}</td>
            <td className="mono">{p.proposed_by.replace("agent_", "")}</td>
            <td className="mono">{p.source_memory_entry}</td>
            <td className="mono">{p.corroboration_count}</td>
            <td><StatusBadge status={promo} /></td>
          </tr>
        </tbody>
      </table>
    </Panel>
  );
}

function LearningView({ learn, setLearn, flash }) {
  function decide(id, status) {
    setLearn({ ...learn, [id]: status });
    flash("proposal " + id + " → " + status);
  }
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
      {D.learningProposals.map((p) => {
        const st = learn[p.id];
        return (
          <div className="panel" key={p.id}>
            <div className="panel-body" style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              <div style={{ display: "flex", justifyContent: "space-between", gap: 12, alignItems: "center" }}>
                <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                  <span className="tag">{p.change_type}</span>
                  <span className="mono" style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-3)" }}>{p.source_signal}</span>
                </div>
                <StatusBadge status={st} />
              </div>
              <div className="rationale">{p.rationale}</div>
              <div style={{ display: "flex", gap: 14, alignItems: "center" }}>
                <span className="mono" style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-3)" }}>confidence {p.confidence} · impact {p.impact}</span>
                <div style={{ marginLeft: "auto", display: "flex", gap: 8 }}>
                  {st === "proposed" && <><Btn size="sm" variant="primary" onClick={() => decide(p.id, "approved")}>Approve</Btn><Btn size="sm" variant="danger" onClick={() => decide(p.id, "rejected")}>Reject</Btn></>}
                  {st === "approved" && <Btn size="sm" onClick={() => decide(p.id, "applied")}>Apply</Btn>}
                  {st === "applied" && <span className="mono" style={{ fontSize: 12, color: "var(--state-success-fg)" }}>applied to org</span>}
                  {st === "rejected" && <span className="mono" style={{ fontSize: 12, color: "var(--fg-3)" }}>dismissed</span>}
                </div>
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

function MemoryView() {
  return (
    <div>
      <Panel title="Collective memory" action={<span className="tag">promoted</span>}>
        <div className="kvlist">
          {D.collectiveMemory.map((m) => (
            <div className="kvrow" key={m.id}>
              <span className="kk">{m.kind}</span>
              <span className="vv">{m.content} <StatusBadge status={m.status} /></span>
            </div>
          ))}
        </div>
      </Panel>
      <Panel title="Individual memory · writer-01">
        <div className="kvlist">
          {D.individualMemory.map((m) => (
            <div className="kvrow" key={m.id}>
              <span className="kk">{m.kind}</span>
              <span className="vv">{m.content} <StatusBadge status={m.status} /></span>
            </div>
          ))}
        </div>
      </Panel>
    </div>
  );
}

function CapabilitiesView() {
  return (
    <Panel flush>
      <table className="table">
        <thead><tr><th>Name</th><th>Default permission</th><th style={{ width: 90 }}>Side-eff.</th><th style={{ width: 90 }}>Risk</th></tr></thead>
        <tbody>
          {D.capabilities.map((c) => (
            <tr key={c.name}>
              <td className="mono">{c.name}</td>
              <td><StatusBadge status={c.default_permission === "enabled" ? "enabled" : c.default_permission === "disabled" ? "disabled" : "pending"} /></td>
              <td className="mono">{c.side_effecting ? "yes" : "no"}</td>
              <td><RiskTag level={c.risk_level} /></td>
            </tr>
          ))}
        </tbody>
      </table>
    </Panel>
  );
}

function CapabilityCallsView() {
  const resByCall = Object.fromEntries(D.capabilityResults.map((r) => [r.call_id, r.status]));
  return (
    <Panel flush>
      <table className="table">
        <thead><tr><th>ID</th><th>Capability</th><th>Requested by</th><th style={{ width: 90 }}>Risk</th><th style={{ width: 110 }}>Result</th></tr></thead>
        <tbody>
          {D.capabilityCalls.map((c) => (
            <tr key={c.id}>
              <td className="mono">{c.id}</td>
              <td className="mono">{c.capability_name}</td>
              <td className="mono">{c.requested_by.replace("agent_", "")}</td>
              <td><RiskTag level={c.risk_level} /></td>
              <td>{resByCall[c.id] ? <StatusBadge status={resByCall[c.id]} /> : <span className="tag">awaiting</span>}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </Panel>
  );
}

function EventsView({ events }) {
  const family = (k) => k.includes("approval.approved") || k.includes("completed") || k.includes("promoted") ? "go" : k.includes("approval.requested") ? "warn" : "";
  return (
    <Panel title="Append-only event log" action={<span className="tag">{events.length} events</span>}>
      <div className="tl">
        {events.map((e) => (
          <div className={"ev " + family(e.kind)} key={e.seq}>
            <span className="seq">{String(e.seq).padStart(3, "0")}</span>
            <span className="kind">{e.kind}</span>
            <span className="actor">{e.actor}</span>
          </div>
        ))}
      </div>
    </Panel>
  );
}

function TracesView() {
  return (
    <Panel flush>
      <table className="table">
        <thead><tr><th>Node</th><th style={{ width: 140 }}>Timestamp</th><th>Run</th></tr></thead>
        <tbody>
          {D.traces.map((t, i) => (
            <tr key={i}><td className="mono">{t.node}</td><td className="mono">{t.timestamp}</td><td className="mono">{t.run_id}</td></tr>
          ))}
        </tbody>
      </table>
    </Panel>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<ConsoleApp />);
