/* Calibrated Ascension HQ — app shell. */
const { useState: useS, useEffect: useE } = React;

const ACCENTS = { emerald: 162, indigo: 274, gold: 78, rose: 14 };

function applyAccent(hue, dark) {
  const r = document.documentElement.style;
  if (dark) {
    r.setProperty("--accent", `oklch(0.82 0.14 ${hue})`);
    r.setProperty("--accent-strong", `oklch(0.88 0.13 ${hue})`);
    r.setProperty("--accent-ink", `oklch(0.86 0.13 ${hue})`);
    r.setProperty("--accent-soft", `oklch(0.30 0.055 ${hue})`);
    r.setProperty("--accent-line", `oklch(0.42 0.07 ${hue})`);
  } else {
    r.setProperty("--accent", `oklch(0.575 0.118 ${hue})`);
    r.setProperty("--accent-strong", `oklch(0.50 0.13 ${hue})`);
    r.setProperty("--accent-ink", `oklch(0.42 0.12 ${hue})`);
    r.setProperty("--accent-soft", `oklch(0.945 0.045 ${hue})`);
    r.setProperty("--accent-line", `oklch(0.85 0.07 ${hue})`);
  }
}

function AgentDetail({ agent, onClose, onChat }) {
  const [instr, setInstr] = useS(agent.kb ? agent.kb.instructions : "");
  const [tab, setTab] = useS("brief");
  const [prompt, setPrompt] = useS("");
  useE(() => { setInstr(agent.kb ? agent.kb.instructions : ""); setTab("brief"); setPrompt(`You are ${agent.name}, the ${agent.role.toLowerCase()} for Calibrated Ascension. ${agent.kb ? agent.kb.instructions : ""}`); }, [agent]);
  const partner = agent.pairWith ? window.HQ_DATA.AGENTS.find((a) => a.id === agent.pairWith) : null;
  const cfg = agent.config || {};
  const lbl = { fontFamily: "var(--mono)", fontSize: 9.5, letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--ink-3)" };
  const tabs = [{ id: "brief", label: "Brief" }, { id: "model", label: "Model & tools" }, { id: "env", label: "Environment" }];
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "oklch(0.2 0.01 90 / 0.4)", backdropFilter: "blur(3px)", zIndex: 60, display: "grid", placeItems: "center", padding: 24 }}>
      <div className="fade" onClick={(e) => e.stopPropagation()} style={{ background: "var(--surface)", border: "1px solid var(--border)", borderRadius: "var(--r-lg)", width: 500, maxWidth: "100%", maxHeight: "88vh", overflow: "auto", boxShadow: "var(--shadow-lg)" }}>
        <div style={{ padding: 22, display: "flex", gap: 14, alignItems: "center", borderBottom: "1px solid var(--border)", position: "sticky", top: 0, background: "var(--surface)", zIndex: 2 }}>
          <Avatar agent={agent} size="lg" />
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 19, fontWeight: 700, fontFamily: "var(--serif)" }}>{agent.name}</div>
            <div style={{ fontSize: 12.5, color: "var(--ink-3)" }}>{agent.role} · {agent.title}</div>
          </div>
          <span className={`status-tag ${agent.status}`}>{agent.status.replace("-", " ")}</span>
        </div>
        <div className="ad-tabs">
          {tabs.map((tb) => <button key={tb.id} className="ad-tab" data-active={tab === tb.id} onClick={() => setTab(tb.id)}>{tb.label}</button>)}
        </div>
        <div style={{ padding: 22 }}>
          {tab === "brief" && (
            <React.Fragment>
              <div style={{ fontSize: 13.5, color: "var(--ink)", lineHeight: 1.5 }}><b>Now ·</b> {agent.now}</div>
              <div style={{ fontSize: 12.5, color: "var(--ink-3)", lineHeight: 1.5, marginTop: 8 }}><b style={{ color: "var(--ink-2)" }}>Last ·</b> {agent.last}</div>
              {partner && <div style={{ fontSize: 12, color: "var(--accent-ink)", marginTop: 10, display: "flex", alignItems: "center", gap: 6 }}>{I.flow} Pairs with {partner.name}</div>}
              <div style={{ ...lbl, margin: "20px 0 8px" }}>Knowledge &amp; instructions</div>
              <textarea className="kb-instr" rows="3" value={instr} onChange={(e) => setInstr(e.target.value)} />
              <div style={{ ...lbl, margin: "16px 0 0" }}>Sources it draws on</div>
              <div className="kb-sources">
                {(agent.kb ? agent.kb.sources : []).map((s, i) => <span key={i} className="kb-src">{I.book} {s}</span>)}
              </div>
              <div style={{ ...lbl, margin: "20px 0 10px" }}>Runs on these loops</div>
              <div className="loops" style={{ borderTop: "none", paddingTop: 0 }}>
                {agent.loops.map((l, i) => <div key={i} className="loop">{l}</div>)}
              </div>
            </React.Fragment>
          )}
          {tab === "model" && (
            <React.Fragment>
              <div className="cfg-badges">
                <span className="cfg-badge managed">{I.spark} Claude Managed Agent</span>
                <span className="cfg-badge">{I.plug} {cfg.mcp}</span>
              </div>
              <div className="field" style={{ marginTop: 16 }}>
                <label>Model</label>
                <select defaultValue={cfg.model}>
                  <option>Claude Opus 4.1</option>
                  <option>Claude Sonnet 4</option>
                  <option>Claude Haiku 4</option>
                </select>
              </div>
              <div style={{ ...lbl, margin: "16px 0 6px" }}>System prompt</div>
              <textarea className="kb-instr" rows="4" value={prompt} onChange={(e) => setPrompt(e.target.value)} />
              <div style={{ ...lbl, margin: "18px 0 8px" }}>Tools (via MCP)</div>
              <div className="kb-sources">{(cfg.tools || []).map((t, i) => <span key={i} className="kb-src">{I.plug} {t}</span>)}</div>
              <div style={{ ...lbl, margin: "18px 0 8px" }}>Skills</div>
              <div className="cfg-skills">
                {(cfg.skills || []).map((sk, i) => (
                  <div key={i} className="cfg-skill">
                    <span className={`skill-tag ${sk.s}`}>{sk.s === "ready" ? "ready" : "to build"}</span>
                    <span className="cfg-skill-n">{sk.n}</span>
                    {sk.s === "needs-build" && <button className="btn btn-ghost btn-sm" style={{ marginLeft: "auto" }}>{I.book} Code skill</button>}
                  </div>
                ))}
                <button className="btn btn-ghost btn-sm" style={{ marginTop: 4 }}>{I.plus} Add a skill</button>
              </div>
            </React.Fragment>
          )}
          {tab === "env" && (
            <React.Fragment>
              <div style={{ ...lbl, marginBottom: 8 }}>Paired environment</div>
              <div className="cfg-env">{I.shield} {cfg.env}</div>
              <div style={{ ...lbl, margin: "18px 0 8px" }}>Infrastructure</div>
              <div className="kb-sources">{(cfg.infra || []).map((t, i) => <span key={i} className="kb-src">{I.gear} {t}</span>)}</div>
              <div style={{ ...lbl, margin: "18px 0 8px" }}>Guardrails</div>
              <div className="cfg-guards">
                {(cfg.guardrails || []).map((g, i) => <div key={i} className="cfg-guard">{I.shield} {g}</div>)}
              </div>
            </React.Fragment>
          )}
          <div className="actions" style={{ marginTop: 22 }}>
            <button className="btn btn-primary btn-sm" onClick={() => onChat(agent)}>{I.send} Chat with {agent.name}</button>
            <button className="btn btn-ghost btn-sm" onClick={onClose}>Close</button>
          </div>
        </div>
      </div>
    </div>
  );
}

function DormantView({ client, onReactivate }) {
  return (
    <div className="center-pad fade">
      <div className="dormant">
        <div className="dormant-orb" style={{ background: client.color }}>{client.initials}</div>
        <div className="dormant-moon">☾</div>
        <h1 className="headline" style={{ marginTop: 18 }}>{client.name} is <em>resting</em>.</h1>
        <p className="sub-intro" style={{ margin: "12px auto 0" }}>This account is dormant — the agents are asleep and nothing runs or bills. Everything is kept exactly as it was: projects, history, GoHighLevel connection, and the full approvals log. Reactivate anytime, even a year from now.</p>
        <div className="actions" style={{ justifyContent: "center", marginTop: 22 }}>
          <button className="btn btn-primary" onClick={onReactivate}>{I.spark} Reactivate account</button>
        </div>
        <div className="dormant-kept">
          <span>{I.check} Projects &amp; files kept</span>
          <span>{I.check} Approvals log kept</span>
          <span>{I.check} GHL connection kept</span>
        </div>
      </div>
    </div>
  );
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "accent": "emerald",
  "layout": "command",
  "rail": "atlas",
  "autoPublish": false
}/*EDITMODE-END*/;

function App() {
  const data = window.HQ_DATA;
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [view, setView] = useS("today");
  const [client, setClient] = useS("agency");
  const [agent, setAgent] = useS(null);
  const [chatAgent, setChatAgent] = useS(window.HQ_DATA.AGENTS[0]);
  const [railTab, setRailTab] = useS("atlas");
  const [removed, setRemoved] = useS({}); // legacy unused
  const [resolved, setResolved] = useS({}); // {clientId: {decisionId: {status, at}}}
  const [clients, setClients] = useS(data.CLIENTS);
  const [cpOpen, setCpOpen] = useS(true);
  const [captured, setCaptured] = useS({}); // {clientId: [projects]}
  const [sentDeliv, setSentDeliv] = useS([]);
  const [composer, setComposer] = useS(null); // { deliverable }
  const [showAdd, setShowAdd] = useS(false);
  const [showAll, setShowAll] = useS(false);
  const [toast, setToast] = useS(null);
  const [projStatus, setProjStatus] = useS({}); // {projectId: status}
  const [projPM, setProjPM] = useS({}); // {projectId: agentId}
  const [settings, setSettings] = useS(DEFAULT_SETTINGS);
  const [showEsc, setShowEsc] = useS(false);
  const [showSettings, setShowSettings] = useS(false);
  const [workflow, setWorkflow] = useS(null); // {item} being inspected
  const [envOn, setEnvOn] = useS(false);
  const [clientView, setClientView] = useS(false);
  const [connectEnv, setConnectEnv] = useS(null); // client object being onboarded to GitHub/Vercel
  const [envConns, setEnvConns] = useS({}); // {clientId: {done, repo, project, domain, plugins}}
  const [approvals, setApprovals] = useS(window.HQ_DATA.APPROVALS || []);
  const [onboarding, setOnboarding] = useS(window.HQ_DATA.ONBOARDING || []);

  function flashToast(msg) { setToast(msg); setTimeout(() => setToast(null), 2600); }

  // Mark an onboarding item received — resolves its linked approval and persists.
  function onMarkOnboarding(taskId, approvalId) {
    setOnboarding((prev) => prev.map((t) => (t.id === taskId ? { ...t, status: "received" } : t)));
    if (approvalId) onResolveApproval(approvalId, "resolved");
    else flashToast("Onboarding item received");
    try {
      if (window.cahq && window.cahq.client) {
        window.cahq.client.from("cahq_onboarding_tasks")
          .update({ status: "received" }).eq("id", taskId)
          .then(({ error }) => { if (error) console.error("[cahq] onboarding update failed", error); });
      }
    } catch (e) { console.error(e); }
  }

  // Resolve/approve an approval — optimistic update + persist to Supabase.
  function onResolveApproval(id, status) {
    setApprovals((prev) => prev.map((a) => (a.id === id ? { ...a, status, resolved_at: new Date().toISOString() } : a)));
    flashToast(status === "approved" ? "Approved" : status === "changes_requested" ? "Changes requested" : "Marked resolved");
    try {
      if (window.cahq && window.cahq.client) {
        window.cahq.client.from("cahq_approvals")
          .update({ status, resolved_at: new Date().toISOString() }).eq("id", id)
          .then(({ error }) => { if (error) console.error("[cahq] approval update failed", error); });
      }
    } catch (e) { console.error(e); }
  }
  function openChat(a) { setChatAgent(a); setRailTab("atlas"); setAgent(null); }

  // theme + accent (persisted; bridged so the account menu stays in sync)
  useE(() => {
    document.documentElement.setAttribute("data-theme", t.theme === "dark" ? "dark" : "light");
    applyAccent(ACCENTS[t.accent] || 162, t.theme === "dark");
    try { localStorage.setItem("cahq_theme", t.theme); } catch (e) { /* ignore */ }
    window.cahqThemeBridge = { get: () => t.theme, set: (v) => setTweak("theme", v) };
  }, [t.theme, t.accent]);

  // restore persisted theme on load; let the account menu open app Settings
  useE(() => {
    try { const s = localStorage.getItem("cahq_theme"); if (s && s !== t.theme) setTweak("theme", s); } catch (e) { /* ignore */ }
    window.cahqOpenSettings = () => setShowSettings(true);
  }, []);

  // switching accounts resets the env switch + client preview (your #3)
  useE(() => { setEnvOn(false); setClientView(false); }, [client]);

  const clientObj = clients.find((c) => c.id === client) || clients[0];
  const ctx = data.CONTEXT[client] || genContext(clientObj);
  const atlas = data.AGENTS[0];
  const dateStr = new Date().toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" });

  const gone = resolved[client] || {};
  const decisions = ctx.decisions.filter((d) => !gone[d.id]);
  const projects = [...(captured[client] || []), ...((ctx.projects) || [])];

  function resolveDecision(cid, id, action) {
    const status = action === "decline" ? "declined" : "approved";
    setResolved((r) => ({ ...r, [cid]: { ...(r[cid] || {}), [id]: { status, at: "just now" } } }));
  }
  function onDecide(id, action) { resolveDecision(client, id, action); }
  function onCapture(project) {
    setCaptured((c) => ({ ...c, [client]: [project, ...(c[client] || [])] }));
    flashToast(`Anubis captured “${project.title.slice(0, 40)}${project.title.length > 40 ? "…" : ""}”`);
  }
  function sendDeliverable(id, to, via) {
    setSentDeliv((s) => [...s, id]);
    setComposer(null);
    const msg = via === "gdoc" ? `Shared a Google Doc with ${clientObj.name}` : via === "drive" ? `Saved to Drive › /Clients/${clientObj.name}` : `Sent to ${to}`;
    flashToast(msg);
  }
  function addClient(c) {
    setClients((list) => [...list, c]);
    setShowAdd(false);
    setClient(c.id);
    flashToast(`${c.name} added${c.connected ? " · GoHighLevel connected" : ""}`);
    if (c.wantsEnv) setTimeout(() => setConnectEnv(c), 350);
  }
  function completeEnv(cid, conns) {
    setEnvConns((e) => ({ ...e, [cid]: conns }));
    setConnectEnv(null);
    const c = clients.find((x) => x.id === cid) || connectEnv;
    flashToast(`Environment connected${c ? " for " + c.name : ""} · agents scoped`);
  }
  function onStatus(id, status) {
    setProjStatus((p) => ({ ...p, [id]: status }));
  }
  function onAssignPM(id, agentId) {
    setProjPM((p) => ({ ...p, [id]: agentId }));
  }
  function retireClient(id) {
    setClients((list) => list.map((c) => (c.id === id ? { ...c, dormant: true } : c)));
    flashToast("Account retired — agents asleep, everything kept");
  }
  function reactivateClient(id) {
    setClients((list) => list.map((c) => (c.id === id ? { ...c, dormant: false } : c)));
    flashToast("Account reactivated — agents waking up");
  }

  // Aggregate everything needing the human, across every (active) account.
  const escItems = [];
  clients.forEach((c) => {
    const cx = data.CONTEXT[c.id];
    if (!cx || c.dormant) return;
    const res = resolved[c.id] || {};
    cx.decisions.filter((d) => !res[d.id]).forEach((d) => escItems.push({ clientId: c.id, id: d.id, kind: "decision", title: d.title, detail: d.detail, tag: d.tag, agent: d.agent, workflow: d.workflow }));
    (cx.risks || []).filter((r) => r.level === "high").forEach((r) => escItems.push({ clientId: c.id, id: "esc-" + r.id, kind: "risk", title: r.title, detail: r.detail }));
  });
  function escApprove(cid, id) {
    resolveDecision(cid, id, "approve");
    flashToast("Approved");
  }
  function escJump(cid) {
    setClient(cid); setView("today"); setShowEsc(false);
  }

  const counts = { decisions: decisions.length };

  function center() {
    if (view === "agents") return <AgentsView data={data} onAgent={setAgent} onChat={openChat} />;
    if (view === "automation") return <AutomationsView data={data} />;
    const accountScoped = ["today", "offers", "traffic", "approvals"].includes(view);
    if (accountScoped && clientObj.dormant) return <DormantView client={clientObj} onReactivate={() => reactivateClient(clientObj.id)} />;
    if (view === "approvals") return <ApprovalsView data={data} ctx={ctx} resolved={resolved[client] || {}} onDecide={onDecide} onWorkflow={(it) => setWorkflow(it)} client={clientObj} approvals={approvals} onResolveApproval={onResolveApproval} />;
    if (view === "offers" || view === "traffic") return <PillarView data={data} ctx={ctx} pillar={view} onAgent={setAgent} />;
    return <TodayView data={data} ctx={ctx} decisions={decisions} onDecide={onDecide} agentObj={atlas} dateStr={dateStr}
      client={clientObj} projects={projects} onCapture={onCapture} onSend={(d) => setComposer({ deliverable: d })} sentDeliv={sentDeliv} projStatus={projStatus} onStatus={onStatus}
      onWorkflow={(d) => setWorkflow({ ...d, clientId: client })} projPM={projPM} onAssignPM={onAssignPM} approvals={approvals} onResolveApproval={onResolveApproval} onboarding={onboarding} onMarkOnboarding={onMarkOnboarding} />;
  }

  return (
    <div className="app" data-layout={t.layout}>
      <Sidebar data={data} clients={clients} view={view} setView={setView} client={client} setClient={setClient} onAgent={openChat} counts={counts} cpOpen={cpOpen} setCpOpen={setCpOpen} onAddClient={() => setShowAdd(true)} onSeeAll={() => setShowAll(true)} onEscalations={() => setShowEsc(true)} onSettings={() => setShowSettings(true)} escCount={escItems.length} theme={t.theme} layout={t.layout} onTheme={(v) => setTweak("theme", v)} onLayout={(v) => setTweak("layout", v)} />

      <div className="col col-center" key={view + client}>
        {["today", "offers", "traffic", "approvals"].includes(view) && !clientObj.agency && !clientObj.dormant && (
          <div className="env-bar" data-on={envOn}>
            <div className="env-left">{I.shield} <b>{clientObj.name}</b> · Prod environment <span className="env-state">{envOn ? "scoped & live" : "read-only"}</span></div>
            <div className="env-right">
              <button className="env-switch" onClick={() => setEnvOn((v) => !v)}><span className="env-track" data-on={envOn}><span className="env-knob"></span></span>{envOn ? "Agents scoped here" : "Switch into this account"}</button>
              {envConns[client] && envConns[client].done
                ? <button className="env-conn-ok" onClick={() => setConnectEnv(clientObj)} title="Manage environment">{I.gitbranch} GitHub · Vercel · {envConns[client].plugins.length} plugins</button>
                : <button className="env-connect" onClick={() => setConnectEnv(clientObj)}>{I.plug} Set up environment</button>}
              <button className="btn btn-ghost btn-sm" onClick={() => setClientView(true)}>{I.users} View as client</button>
            </div>
          </div>
        )}
        {center()}
      </div>

      <div className="col rail">
        <div className="rail-tabs">
          <button className="rail-tab" data-active={railTab === "atlas"} onClick={() => setRailTab("atlas")}>Chat</button>
          <button className="rail-tab" data-active={railTab === "auto"} onClick={() => setRailTab("auto")}>Live automation</button>
        </div>
        {railTab === "atlas"
          ? <ChatDock key={chatAgent.id + client} agent={chatAgent} ctx={ctx} allAgents={data.AGENTS} onSwitch={openChat} onOpenAuto={() => setRailTab("auto")} onProfile={(a) => setAgent(a)} />
          : <AutomationRunner auto={data.AUTOMATION} agents={data.AGENTS} autoPublish={t.autoPublish} />}
      </div>

      {agent && <AgentDetail agent={agent} onClose={() => setAgent(null)} onChat={openChat} />}

      {composer && <OutputComposer deliverable={composer.deliverable} client={clientObj} onClose={() => setComposer(null)} onSend={sendDeliverable} />}
      {showAdd && <AddClientModal onClose={() => setShowAdd(false)} onAdd={addClient} />}      {showAll && <AllClientsModal clients={clients} current={client} onSelect={(id) => { setClient(id); setShowAll(false); }} onClose={() => setShowAll(false)} onAdd={() => { setShowAll(false); setShowAdd(true); }} onRetire={retireClient} onReactivate={reactivateClient} />}
      {showEsc && <EscalationInbox items={escItems} clients={clients} onApprove={escApprove} onJump={escJump} onInspect={(it) => { setShowEsc(false); setWorkflow(it); }} onClose={() => setShowEsc(false)} />}
      {showSettings && <SettingsModal settings={settings} setSettings={setSettings} onClose={() => setShowSettings(false)} />}
      {workflow && <WorkflowDetail item={workflow} data={data} clients={clients} onApprove={(cid, id) => { resolveDecision(cid, id, "approve"); setWorkflow(null); flashToast("Approved"); }} onDecline={(cid, id) => { resolveDecision(cid, id, "decline"); setWorkflow(null); }} onChat={(a) => { openChat(a); setWorkflow(null); }} onClose={() => setWorkflow(null)} />}
      {toast && <div className="toast">{I.check} {toast}</div>}
      {clientView && <ClientPortal client={clientObj} onExit={() => setClientView(false)} flashToast={flashToast} />}
      {connectEnv && <ConnectEnvModal client={connectEnv} initial={envConns[connectEnv.id]} onClose={() => setConnectEnv(null)} onComplete={(conns) => completeEnv(connectEnv.id, conns)} />}

      <TweaksPanel>
        <TweakSection label="Theme" />
        <TweakRadio label="Mode" value={t.theme} options={["light", "dark"]} onChange={(v) => setTweak("theme", v)} />
        <TweakSelect label="Accent" value={t.accent} options={["emerald", "indigo", "gold", "rose"]} onChange={(v) => setTweak("accent", v)} />
        <TweakSection label="Layout" />
        <TweakRadio label="Workspace" value={t.layout} options={["command", "focus"]} onChange={(v) => setTweak("layout", v)} />
        <TweakSection label="Automation" />
        <TweakToggle label="Auto-publish (skip my approval)" value={t.autoPublish} onChange={(v) => setTweak("autoPublish", v)} />
      </TweaksPanel>
    </div>
  );
}

// Bootstrap: load live operating data from Supabase (if available), then mount.
// Falls back to the built-in mock if the fetch is unavailable or fails.
(function cahqBootstrap() {
  const ready = window.cahqDataReady || Promise.resolve(null);
  Promise.resolve(ready)
    .then((db) => {
      try {
        if (!db) return;
        if (db.agents && db.agents.length) window.HQ_DATA.AGENTS = db.agents;
        if (db.accounts && db.accounts.length) window.HQ_DATA.CLIENTS = db.accounts;
        if (db.approvals) window.HQ_DATA.APPROVALS = db.approvals;
        if (db.onboarding) window.HQ_DATA.ONBOARDING = db.onboarding;
        if (db.projectsByAccount) {
          const pba = db.projectsByAccount;
          Object.keys(pba).forEach((aid) => {
            const acc = (window.HQ_DATA.CLIENTS || []).find((c) => c.id === aid) || { id: aid, name: aid, connected: true };
            const base = window.HQ_DATA.CONTEXT[aid] ||
              (window.genContext ? window.genContext(acc) : { greeting: "", metrics: {}, decisions: [], tomorrow: {}, risks: [], projects: [] });
            window.HQ_DATA.CONTEXT[aid] = Object.assign({}, base, { projects: pba[aid] });
          });
        }
      } catch (e) { console.error(e); }
    })
    .catch(() => {})
    .finally(() => {
      ReactDOM.createRoot(document.getElementById("root")).render(<App />);
    });
})();
