/**
 * SecurityTab — native security surfaces in the panel (KC.D).
 *
 * Promotes two high-value security apps from hosted iframes to first-class
 * native panels that call the live API with the extension's token (like
 * Apps/Skills/Contracts/Observer/Daemon already do):
 *
 *   • Zeq SSL — each machine is its own CA. Issue / list / revoke the machine's
 *               SSL credentials (1-RTT HMAC handshake creds). Endpoints:
 *               GET /api/ssl/credentials?machine=<slug>, POST .../issue, .../revoke.
 *   • Zeq AV  — antivirus mesh: threat feed + registered devices for the machine.
 *               GET /api/av/threats?slug=<slug>, GET /api/av/devices.
 *
 * ZSC (secret vault) and Edge are NOT promoted here: their write APIs gate on a
 * state-machine API key (zsm_…) which the panel session doesn't currently hold.
 * They stay hosted (signed in via the auth-bridge) until the machine-key path
 * is wired into the SW.
 *
 * @version 1.287.11
 * @license CC BY 4.0 — Zeq. H / Zeq 1.287 Hz Limited
 */
const SecurityTab = (() => {
  "use strict";
  let _cid = null, _sub = "ssl", _origin = "";

  function esc(s) { return String(s == null ? "" : s).replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c])); }
  function sw(msg) { return new Promise((res) => { try { chrome.runtime.sendMessage(msg, (r) => res(chrome.runtime.lastError ? null : r)); } catch (_) { res(null); } }); }
  function authed() { return typeof ZeqAuth !== "undefined" && ZeqAuth.isAuthenticated(); }

  const STYLE = "<style>" +
    ".zs{padding:12px;overflow-y:auto;height:100%}" +
    ".zs .modes{display:flex;gap:6px;margin-bottom:10px}" +
    ".zs .mode{flex:1;padding:7px;font-size:12px;font-weight:600;border:1px solid var(--border);border-radius:7px;background:transparent;color:var(--text-secondary);cursor:pointer}" +
    ".zs .mode.active{border-color:var(--accent-mint);color:var(--accent-mint);background:rgba(0,255,136,.06)}" +
    ".zs h3{font-size:13px;margin:0 0 3px;color:var(--text-primary)}" +
    ".zs .lead{font-size:11px;color:var(--text-muted);line-height:1.5;margin:0 0 10px}" +
    ".zs .card{border:1px solid var(--border);border-radius:9px;padding:10px;margin-bottom:9px;background:var(--bg-secondary)}" +
    ".zs .row{display:flex;gap:7px;align-items:center}" +
    ".zs select{flex:0 0 auto;padding:7px 9px;background:rgba(0,0,0,.45);border:1px solid var(--border);border-radius:7px;color:var(--text-primary);font-size:12px}" +
    ".zs .btn{flex:1;padding:9px;border-radius:8px;border:1px solid var(--accent-mint);background:var(--accent-mint);color:#02120a;font-weight:700;font-size:12px;cursor:pointer}" +
    ".zs .btn:disabled{opacity:.5}" +
    ".zs .cred{border:1px solid var(--border);border-radius:7px;padding:8px;margin-top:7px;font-size:11px}" +
    ".zs .kid{font-family:'JetBrains Mono',monospace;color:#00d4ff;word-break:break-all}" +
    ".zs .meta{font-size:10px;color:var(--text-muted);margin-top:3px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}" +
    ".zs .tag{font-size:9px;padding:2px 6px;border-radius:5px;font-weight:700}" +
    ".zs .valid{background:rgba(0,255,136,.14);color:var(--accent-mint)}.zs .invalid{background:rgba(255,120,120,.14);color:#ff8a8a}" +
    ".zs .mini{font-size:9px;padding:2px 7px;border-radius:5px;border:1px solid var(--border);background:transparent;color:var(--text-secondary);cursor:pointer}" +
    ".zs .mini:hover{border-color:#ff8a8a;color:#ff8a8a}" +
    ".zs pre{background:rgba(0,0,0,.5);border:1px solid var(--border);border-radius:7px;padding:8px;font-size:10px;color:#ffd166;white-space:pre-wrap;word-break:break-all;margin:7px 0 0;font-family:'JetBrains Mono',monospace}" +
    ".zs .stat{display:flex;gap:10px;margin-bottom:8px}" +
    ".zs .stat .b{flex:1;border:1px solid var(--border);border-radius:8px;padding:9px;text-align:center}" +
    ".zs .stat .v{font-size:20px;font-weight:800;color:var(--accent-mint)}.zs .stat .k{font-size:9.5px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em}" +
    ".zs .msg{font-size:11px;margin-top:7px;min-height:14px}.zs .ok{color:var(--accent-mint)}.zs .err{color:#ff5577}" +
    ".zs .empty{font-size:11px;color:var(--text-muted);line-height:1.5}" +
    "</style>";

  function shell(inner) {
    const tab = (id, label) => '<button class="mode' + (_sub === id ? " active" : "") + '" data-sub="' + id + '">' + label + "</button>";
    return STYLE + '<div class="zs">' +
      '<div class="modes">' + tab("ssl", "SSL") + tab("zsc", "Secrets") + tab("av", "AV") + tab("edge", "Edge") + "</div>" +
      inner + "</div>";
  }

  function render(inner) {
    const c = document.getElementById(_cid);
    if (!c) return;
    if (!authed()) { c.innerHTML = STYLE + '<div class="zs"><div class="empty">Sign in to manage your machine’s SSL credentials and AV mesh.</div></div>'; return; }
    c.innerHTML = shell(inner);
    c.querySelectorAll(".mode[data-sub]").forEach((b) => b.addEventListener("click", () => { _sub = b.getAttribute("data-sub"); load(); }));
    if (_sub === "ssl") wireSsl();
    else if (_sub === "zsc") wireZsc();
    else if (_sub === "edge") wireEdge();
    // av is read-only
  }

  // ── SSL ──────────────────────────────────────────────────────────────────
  function sslCard(creds) {
    const rows = (creds || []).map((cr) =>
      '<div class="cred"><div class="kid">' + esc(cr.kid || cr.id) + "</div>" +
      '<div class="meta"><span class="tag ' + (cr.valid_now ? "valid" : "invalid") + '">' + (cr.valid_now ? "VALID" : (cr.revoked_at_zeqond ? "REVOKED" : "EXPIRED")) + "</span>" +
      "<span>mode " + esc(cr.mode) + "</span>" + (cr.expires_at_zeqond ? "<span>exp z" + esc(String(cr.expires_at_zeqond)) + "</span>" : "") +
      (cr.valid_now ? '<button class="mini" data-revoke="' + esc(cr.id) + '">Revoke</button>' : "") + "</div></div>"
    ).join("") || '<div class="empty">No credentials yet. Issue one — your machine is its own CA.</div>';
    return "<h3>Zeq SSL — credential manager</h3>" +
      '<p class="lead">Each machine is its own CA. Identity is an equation-hash row; the handshake is a 1-RTT HMAC derivation. Issue and manage this machine’s credentials.</p>' +
      '<div class="card"><div class="row"><select id="ssl-mode"><option value="A">Mode A (automatic)</option><option value="B">Mode B (manual)</option></select>' +
      '<button class="btn" id="ssl-issue">Issue credential</button></div>' +
      '<div class="msg" id="ssl-msg"></div><div id="ssl-secret"></div></div>' +
      '<div class="card"><label style="font-size:10px;color:var(--text-muted)">Credentials</label>' + rows + "</div>";
  }
  function wireSsl() {
    const btn = document.getElementById("ssl-issue");
    if (btn) btn.addEventListener("click", async () => {
      btn.disabled = true; btn.textContent = "Issuing…";
      const mode = (document.getElementById("ssl-mode") || {}).value || "A";
      const r = await sw({ type: "sslIssue", mode });
      btn.disabled = false; btn.textContent = "Issue credential";
      const msg = document.getElementById("ssl-msg");
      if (!r || !r.success) { if (msg) { msg.className = "msg err"; msg.textContent = "Issue failed: " + ((r && r.error) || "?"); } return; }
      if (msg) { msg.className = "msg ok"; msg.textContent = "✓ Credential issued — secret shown once below."; }
      const sec = document.getElementById("ssl-secret");
      const d = r.data || {};
      if (sec && d.secret_seed_hex) sec.innerHTML = '<pre>secret_seed (save now, shown once):\n' + esc(d.secret_seed_hex) + "</pre>";
      load();
    });
    document.querySelectorAll("[data-revoke]").forEach((b) => b.addEventListener("click", async () => {
      if (!confirm("Revoke this credential?")) return;
      b.disabled = true;
      const r = await sw({ type: "sslRevoke", credentialId: b.getAttribute("data-revoke") });
      const msg = document.getElementById("ssl-msg");
      if (msg) { msg.className = "msg " + (r && r.success ? "ok" : "err"); msg.textContent = r && r.success ? "Revoked." : "Revoke failed."; }
      load();
    }));
  }

  // ── AV ─────────────────────────────────────────────────────────────────────
  function avCard(threats, devices, threatCount) {
    const tRows = (threats || []).slice(0, 30).map((t) =>
      '<div class="cred"><div class="kid">' + esc(t.kind || t.type || t.signature || "threat") + "</div>" +
      '<div class="meta"><span>' + esc(t.severity || t.level || "—") + "</span>" + (t.device || t.device_id ? "<span>" + esc(t.device || t.device_id) + "</span>" : "") +
      (t.at_zeqond || t.zeqond ? "<span>z" + esc(String(t.at_zeqond || t.zeqond)) + "</span>" : "") + "</div></div>"
    ).join("") || '<div class="empty">No threats reported — mesh is clean.</div>';
    return "<h3>Zeq AV — mesh status</h3>" +
      '<p class="lead">The antivirus mesh: registered devices stream threat signals into your machine. Read-only status here; claim devices via the AV app or API.</p>' +
      '<div class="stat"><div class="b"><div class="v">' + (devices ? devices.length : 0) + '</div><div class="k">Devices</div></div>' +
      '<div class="b"><div class="v">' + (threatCount || 0) + '</div><div class="k">Threats</div></div></div>' +
      '<div class="card"><label style="font-size:10px;color:var(--text-muted)">Threat feed</label>' + tRows + "</div>";
  }
  function wireAv() { /* read-only; nothing to wire */ }

  // ── ZSC (secret vault) ──────────────────────────────────────────────────────
  function zscCard(secrets, note) {
    const rows = (secrets || []).map((s) => {
      const name = s.name || s.key || s.id || "secret";
      return '<div class="cred"><div class="kid">' + esc(name) + "</div>" +
        '<div class="meta">' + (s.env ? "<span>" + esc(s.env) + "</span>" : "") + (s.app ? "<span>" + esc(s.app) + "</span>" : "") +
        (s.updated_at || s.rotated_at ? "<span>upd " + esc(String(s.updated_at || s.rotated_at).slice(0, 19)) + "</span>" : "") +
        '<span class="tag valid">SEALED</span></div></div>';
    }).join("") || '<div class="empty">' + esc(note || "No secrets in this namespace yet.") + "</div>";
    return "<h3>ZSC — secure context</h3>" +
      '<p class="lead">Your machine’s secret vault: AES-256-GCM at rest, audit-chained reads. Values are never shown back — set and rotate, the machine reads them at runtime.</p>' +
      '<div class="card"><div class="row" style="gap:6px"><input id="zsc-name" placeholder="name (e.g. STRIPE_KEY)" style="flex:1;padding:7px 9px;background:rgba(0,0,0,.45);border:1px solid var(--border);border-radius:7px;color:var(--text-primary);font-size:12px"></div>' +
      '<input id="zsc-value" placeholder="value (stored encrypted, never echoed)" style="width:100%;margin-top:6px;padding:7px 9px;background:rgba(0,0,0,.45);border:1px solid var(--border);border-radius:7px;color:var(--text-primary);font-size:12px">' +
      '<button class="btn" id="zsc-put" style="margin-top:7px">Set secret</button>' +
      '<div class="msg" id="zsc-msg"></div></div>' +
      '<div class="card"><label style="font-size:10px;color:var(--text-muted)">Secrets (default · production)</label>' + rows + "</div>";
  }
  function wireZsc() {
    const btn = document.getElementById("zsc-put");
    if (btn) btn.addEventListener("click", async () => {
      const name = (document.getElementById("zsc-name") || {}).value || "";
      const value = (document.getElementById("zsc-value") || {}).value || "";
      const msg = document.getElementById("zsc-msg");
      if (!name || !value) { if (msg) { msg.className = "msg err"; msg.textContent = "Name and value required."; } return; }
      btn.disabled = true; btn.textContent = "Sealing…";
      const r = await sw({ type: "zscPut", name, value });
      btn.disabled = false; btn.textContent = "Set secret";
      if (!r || !r.success) { if (msg) { msg.className = "msg err"; msg.textContent = "Set failed: " + ((r && (r.data && r.data.error)) || (r && r.error) || ("HTTP " + (r && r.status))); } return; }
      if (msg) { msg.className = "msg ok"; msg.textContent = "✓ Sealed " + name; }
      load();
    });
  }

  // ── Edge ────────────────────────────────────────────────────────────────────
  function edgeCard(sites, note) {
    const rows = (sites || []).map((s) =>
      '<div class="cred"><div class="kid">' + esc(s.hostname || s.host || s.domain || s.id) + "</div>" +
      '<div class="meta">' + (s.status ? "<span>" + esc(s.status) + "</span>" : "") + (s.origin ? "<span>" + esc(s.origin) + "</span>" : "") + "</div></div>"
    ).join("") || '<div class="empty">' + esc(note || "No sites connected yet. Add one to route it through Zeq Edge.") + "</div>";
    return "<h3>Zeq Edge — sites</h3>" +
      '<p class="lead">Route a site through Zeq Edge (Workers). Connect a hostname to your machine; the edge serves it with your machine’s identity and policies.</p>' +
      '<div class="card"><input id="edge-host" placeholder="hostname (e.g. shop.example.com)" style="width:100%;padding:7px 9px;background:rgba(0,0,0,.45);border:1px solid var(--border);border-radius:7px;color:var(--text-primary);font-size:12px">' +
      '<button class="btn" id="edge-add" style="margin-top:7px">Connect site</button><div class="msg" id="edge-msg"></div></div>' +
      '<div class="card"><label style="font-size:10px;color:var(--text-muted)">Connected sites</label>' + rows + "</div>";
  }
  function wireEdge() {
    const btn = document.getElementById("edge-add");
    if (btn) btn.addEventListener("click", async () => {
      const host = (document.getElementById("edge-host") || {}).value || "";
      const msg = document.getElementById("edge-msg");
      if (!host) { if (msg) { msg.className = "msg err"; msg.textContent = "Hostname required."; } return; }
      btn.disabled = true; btn.textContent = "Connecting…";
      const r = await sw({ type: "edgeAdd", hostname: host });
      btn.disabled = false; btn.textContent = "Connect site";
      if (!r || !r.success) { if (msg) { msg.className = "msg err"; msg.textContent = "Connect failed: " + ((r && r.data && r.data.error) || (r && r.error) || ("HTTP " + (r && r.status))); } return; }
      if (msg) { msg.className = "msg ok"; msg.textContent = "✓ Connected " + host; }
      load();
    });
  }

  async function load() {
    render('<div class="empty">Loading…</div>');
    if (!authed()) return;
    if (_sub === "ssl") {
      const r = await sw({ type: "sslList" });
      render(sslCard((r && r.success && r.data && r.data.credentials) || [])); return;
    }
    if (_sub === "zsc") {
      const r = await sw({ type: "zscList" });
      const list = (r && r.data && (r.data.secrets || r.data.items || r.data.entries || r.data.rows)) || [];
      render(zscCard(list, r && !r.success ? "Couldn't read secrets (" + ((r.data && r.data.error) || ("HTTP " + r.status)) + ")." : "")); return;
    }
    if (_sub === "edge") {
      const r = await sw({ type: "edgeList" });
      const sites = (r && r.data && (r.data.sites || r.data.items || r.data.rows)) || [];
      render(edgeCard(sites, r && !r.success ? "Couldn't read sites (" + ((r.data && r.data.error) || ("HTTP " + r.status)) + ")." : "")); return;
    }
    const r = await sw({ type: "avStatus" });
    if (r && r.origin) _origin = r.origin;
    render(avCard((r && r.threats) || [], (r && r.devices) || [], (r && r.threatCount) || 0));
  }

  function init(cid) { _cid = cid; load(); }
  function stop() {}
  return { init, stop };
})();
if (typeof module !== "undefined" && module.exports) { module.exports = SecurityTab; }
