/**
 * ContractsTab — native State Contracts catalogue inside the extension panel.
 *
 * Two modes:
 *   • Templates — deployable contract templates (GET /api/contracts/templates,
 *     detail /:id). One-click deploy to the user's machine
 *     (POST /api/chain/:slug/contracts { definition }).
 *   • Protocols — the API protocol reference (GET /api/protocols, 241 endpoints).
 *
 * Depends on: window.ZeqConfig, window.ZeqAuth.
 *
 * @version 1.287.6
 * @license CC BY 4.0 — Zeq. H / Zeq 1.287 Hz Limited
 */
const ContractsTab = (() => {
  "use strict";

  let _cid = null;
  let _mode = "templates"; // templates | protocols
  let _templates = [];
  let _tcats = [];
  let _protocols = [];
  let _loaded = { templates: false, protocols: false };
  let _cat = "all";
  let _q = "";
  let _view = "list"; // list | detail
  let _current = null;

  function esc(s) { return String(s == null ? "" : s).replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c])); }
  async function _api() { return await ZeqConfig.api(); }
  function _authed() { return typeof ZeqAuth !== "undefined" && ZeqAuth.isAuthenticated(); }
  function _headers() {
    const h = { "Content-Type": "application/json" };
    if (_authed()) Object.assign(h, ZeqAuth.getHeaders());
    return h;
  }
  function _slug() { const u = ZeqAuth.getUser && ZeqAuth.getUser(); return u && u.zid ? String(u.zid).toLowerCase() : null; }

  async function _loadTemplates() {
    try {
      const r = await fetch((await _api()) + "/contracts/templates", { headers: _headers() });
      const j = await r.json().catch(() => ({}));
      _templates = j.templates || [];
      _tcats = j.categories || [];
      _loaded.templates = true;
    } catch (_) {}
  }
  async function _loadProtocols() {
    try {
      const r = await fetch((await _api()) + "/protocols", { headers: _headers() });
      const j = await r.json().catch(() => ({}));
      _protocols = j.protocols || [];
      _loaded.protocols = true;
    } catch (_) {}
  }

  const STYLE = "<style>" +
    ".zct-wrap{padding:12px;overflow-y:auto;height:100%}" +
    ".zct-modes{display:flex;gap:6px;margin-bottom:10px}" +
    ".zct-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}" +
    ".zct-mode.active{border-color:var(--accent-mint);color:var(--accent-mint);background:rgba(0,255,136,.06)}" +
    ".zct-search{width:100%;padding:9px 12px;background:rgba(0,0,0,.45);border:1px solid var(--border);border-radius:8px;color:var(--text-primary);font-size:13px;outline:none;box-sizing:border-box;margin-bottom:10px}" +
    ".zct-search:focus{border-color:var(--accent-mint)}" +
    ".zct-chips{display:flex;gap:5px;flex-wrap:wrap;margin-bottom:10px}" +
    ".zct-chip{font-size:10px;padding:4px 8px;border-radius:12px;border:1px solid var(--border);background:transparent;color:var(--text-secondary);cursor:pointer;white-space:nowrap}" +
    ".zct-chip.active{border-color:var(--accent-mint);color:var(--accent-mint)}" +
    ".zct-card{width:100%;text-align:left;padding:10px;margin-bottom:8px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:10px;cursor:pointer}" +
    ".zct-card:hover{border-color:var(--accent-mint)}" +
    ".zct-name{font-weight:600;font-size:13px;color:var(--text-primary)}" +
    ".zct-meta{font-size:10.5px;color:var(--text-muted);margin-top:2px}" +
    ".zct-desc{font-size:11px;color:var(--text-secondary);line-height:1.45;margin-top:3px}" +
    ".zct-back{background:transparent;border:1px solid var(--border);border-radius:6px;color:var(--text-primary);font-size:12px;padding:5px 9px;cursor:pointer;margin-bottom:10px}" +
    ".zct-h{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted);margin:12px 0 4px}" +
    ".zct-btn{width:100%;margin-top:10px;padding:11px;border-radius:8px;border:1px solid var(--accent-mint);background:var(--accent-mint);color:#02120a;font-weight:700;font-size:13px;cursor:pointer}" +
    ".zct-btn:disabled{opacity:.5}" +
    ".zct-pre{white-space:pre-wrap;word-break:break-word;font-size:10.5px;background:rgba(0,0,0,.5);border:1px solid var(--border);border-radius:8px;padding:10px;max-height:220px;overflow:auto}" +
    ".zct-meth{font-family:monospace;font-size:9px;color:var(--accent-mint);border:1px solid var(--border);border-radius:6px;padding:0 5px;margin-right:5px}" +
    ".zct-err{color:var(--accent-red);font-size:11.5px;margin-top:8px}" +
    ".zct-ok{color:var(--accent-mint);font-size:11.5px;margin-top:8px}" +
    "</style>";

  function _modes() {
    return '<div class="zct-modes">' +
      '<button class="zct-mode' + (_mode === "templates" ? " active" : "") + '" data-mode="templates">Templates</button>' +
      '<button class="zct-mode' + (_mode === "protocols" ? " active" : "") + '" data-mode="protocols">Protocols</button></div>';
  }

  function _renderTemplatesList() {
    const cats = ["all"].concat(_tcats);
    const chips = cats.map((c) => '<button class="zct-chip' + (c === _cat ? " active" : "") + '" data-cat="' + esc(c) + '">' + esc(c === "all" ? "All" : c) + "</button>").join("");
    const q = _q.trim().toLowerCase();
    const list = _templates.filter((t) => (_cat === "all" || t.category === _cat) && (!q || (t.name || "").toLowerCase().includes(q) || (t.description || "").toLowerCase().includes(q) || (t.id || "").toLowerCase().includes(q)));
    const cards = list.map((t) =>
      '<button class="zct-card" data-id="' + esc(t.id) + '"><div class="zct-name">' + esc(t.name) + "</div>" +
      '<div class="zct-meta">' + esc(t.category || "") + (t.operators_used ? " · " + esc((t.operators_used || []).join(", ")) : "") + "</div>" +
      '<div class="zct-desc">' + esc(t.description || "") + "</div></button>"
    ).join("") || '<p style="color:var(--text-muted);font-size:12px">No templates match.</p>';
    return STYLE + '<div class="zct-wrap">' + _modes() +
      '<input class="zct-search" id="zct-search" placeholder="Search templates…" value="' + esc(_q) + '">' +
      '<div class="zct-chips">' + chips + "</div>" + cards + "</div>";
  }

  function _renderTemplateDetail(t) {
    const ops = (t.operators_used || []).join(", ");
    const uses = (t.use_cases || []).map((u) => "<li>" + esc(u) + "</li>").join("");
    const def = t.definition ? JSON.stringify(t.definition, null, 2) : "";
    return STYLE + '<div class="zct-wrap">' +
      '<button class="zct-back" id="zct-back">‹ Templates</button>' +
      '<div class="zct-name" style="font-size:16px">' + esc(t.name) + "</div>" +
      '<div class="zct-meta">' + esc(t.category || "") + (ops ? " · operators: " + esc(ops) : "") + "</div>" +
      '<div class="zct-desc" style="margin-top:6px">' + esc(t.description || "") + "</div>" +
      (uses ? '<div class="zct-h">Use cases</div><ul style="font-size:11.5px;color:var(--text-secondary);line-height:1.5;padding-left:18px;margin:0">' + uses + "</ul>" : "") +
      '<div class="zct-h">Definition</div><pre class="zct-pre">' + esc(def.slice(0, 3000)) + (def.length > 3000 ? "\n…" : "") + "</pre>" +
      (_authed()
        ? '<button class="zct-btn" id="zct-deploy">Deploy to my machine</button>'
        : '<p class="zct-meta" style="margin-top:10px">Sign in to deploy this contract to your machine.</p>') +
      '<div class="zct-err" id="zct-err" style="display:none"></div>' +
      '<div class="zct-ok" id="zct-ok" style="display:none"></div>' +
      "</div>";
  }

  function _renderProtocols() {
    const q = _q.trim().toLowerCase();
    const list = _protocols.filter((p) => !q || (p.name || "").toLowerCase().includes(q) || (p.description || "").toLowerCase().includes(q) || (p.endpoint || "").toLowerCase().includes(q) || (p.category || "").toLowerCase().includes(q)).slice(0, 200);
    const rows = list.map((p) =>
      '<div class="zct-card" style="cursor:default"><div class="zct-name"><span class="zct-meth">' + esc(p.method || "GET") + "</span>" + esc(p.name || p.id) + "</div>" +
      '<div class="zct-meta" style="font-family:monospace">' + esc(p.endpoint || "") + " · " + esc(p.category || "") + " · auth: " + esc(p.auth || "none") + "</div>" +
      '<div class="zct-desc">' + esc(p.description || "") + "</div></div>"
    ).join("") || '<p style="color:var(--text-muted);font-size:12px">No protocols match.</p>';
    return STYLE + '<div class="zct-wrap">' + _modes() +
      '<input class="zct-search" id="zct-search" placeholder="Search ' + _protocols.length + ' protocols…" value="' + esc(_q) + '">' +
      rows + "</div>";
  }

  function _render() {
    const c = document.getElementById(_cid);
    if (!c) return;
    const loadingNow = (_mode === "templates" && !_loaded.templates) || (_mode === "protocols" && !_loaded.protocols);
    if (loadingNow) { c.innerHTML = STYLE + '<div class="zct-wrap">' + _modes() + '<p style="color:var(--text-muted);font-size:12px">Loading…</p></div>'; _bindModes(c); return; }

    if (_mode === "templates" && _view === "detail" && _current) { c.innerHTML = _renderTemplateDetail(_current); _bindDetail(c); return; }
    c.innerHTML = _mode === "templates" ? _renderTemplatesList() : _renderProtocols();
    _bindModes(c);
    const s = document.getElementById("zct-search");
    if (s) { s.addEventListener("input", (e) => { _q = e.target.value; _render(); }); const v = s.value; s.focus(); s.setSelectionRange(v.length, v.length); }
    c.querySelectorAll(".zct-chip").forEach((b) => b.addEventListener("click", () => { _cat = b.getAttribute("data-cat"); _render(); }));
    c.querySelectorAll("[data-id]").forEach((b) => b.addEventListener("click", async () => {
      const id = b.getAttribute("data-id");
      try { const r = await fetch((await _api()) + "/contracts/templates/" + encodeURIComponent(id), { headers: _headers() }); const j = await r.json().catch(() => ({})); _current = j.template || _templates.find((t) => t.id === id); }
      catch (_) { _current = _templates.find((t) => t.id === id); }
      _view = "detail"; _render();
    }));
  }

  function _bindModes(c) {
    c.querySelectorAll(".zct-mode").forEach((b) => b.addEventListener("click", async () => {
      _mode = b.getAttribute("data-mode"); _view = "list"; _q = ""; _cat = "all";
      _render();
      if (_mode === "templates" && !_loaded.templates) { await _loadTemplates(); _render(); }
      if (_mode === "protocols" && !_loaded.protocols) { await _loadProtocols(); _render(); }
    }));
  }

  function _bindDetail(c) {
    c.querySelector("#zct-back")?.addEventListener("click", () => { _view = "list"; _current = null; _render(); });
    c.querySelector("#zct-deploy")?.addEventListener("click", async (e) => {
      const err = document.getElementById("zct-err"), ok = document.getElementById("zct-ok");
      const slug = _slug();
      if (!slug) { if (err) { err.textContent = "Sign in first."; err.style.display = "block"; } return; }
      const btn = e.currentTarget; btn.disabled = true; btn.textContent = "Deploying…";
      if (err) err.style.display = "none"; if (ok) ok.style.display = "none";
      try {
        const r = await fetch((await _api()) + "/chain/" + encodeURIComponent(slug) + "/contracts", {
          method: "POST", headers: _headers(), body: JSON.stringify({ definition: _current.definition }),
        });
        const j = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(j.error_description || j.error || ("Deploy failed (" + r.status + ")"));
        if (ok) { ok.textContent = "Deployed ✓ — contract " + (j.id || j.contract?.id || "added") + " on " + slug; ok.style.display = "block"; }
        btn.textContent = "Deployed ✓";
      } catch (ex) {
        if (err) { err.textContent = ex.message || "Deploy failed"; err.style.display = "block"; }
        btn.disabled = false; btn.textContent = "Deploy to my machine";
      }
    });
  }

  async function init(cid) {
    _cid = cid; _view = "list"; _current = null; _q = ""; _cat = "all";
    _render();
    if (!_loaded.templates) { await _loadTemplates(); _render(); }
  }

  return { init };
})();

if (typeof module !== "undefined" && module.exports) { module.exports = ContractsTab; }
