/**
 * Zeq Auth Bridge — carry the extension's identity into the framework web apps.
 *
 * Runs at document_start on the fork origins (zeqstate.com, zeq.dev, …). The web
 * apps authenticate by reading localStorage.zeq_auth_token / zeq_zid on their
 * own origin; the extension's session lives in chrome.storage (extension origin),
 * so without this bridge a hosted app shows a SECOND login. This mirrors the
 * extension's token into the page's localStorage before the app's auth check,
 * so every fork page + in-panel hosted app is signed in with the same identity.
 *
 * Privacy: writes only the public ZID + the bearer token the user already holds,
 * and only onto first-party fork origins the manifest already permits.
 *
 * @version 1.287.6
 * @license CC BY 4.0 — Zeq. H / Zeq 1.287 Hz Limited
 */
(() => {
  "use strict";
  const RELOAD_FLAG = "zeq_bridge_reloaded_v1";

  // ── KC.B — embed/panel-fit: when the extension hosts a fork app in the
  // ~380px panel it loads with ?embed=1. Hide the site/app chrome and reflow
  // to a tight column so the app fits. Injected at document_start so chrome
  // never flashes. Scoped to embed=1 → never affects normal browsing.
  try {
    if (/[?&]embed=(1|true)\b/.test(location.search)) {
      const css =
        "#zeq-app-nav,#site-nav,[data-zeq-footer],.crumb,.ecosystem-dropdown,.site-footer,.zeq-landing-nav{display:none!important}" +
        "html,body{margin:0!important;background:#05070d!important}" +
        "body{padding:8px!important;min-width:0!important;overflow-x:hidden!important}" +
        "main,.container,.wrap,.shell{max-width:100%!important;width:100%!important;padding-left:0!important;padding-right:0!important}";
      const st = document.createElement("style");
      st.id = "zeq-embed-fit"; st.textContent = css;
      (document.head || document.documentElement).appendChild(st);
      document.documentElement.classList.add("zeq-embed");
    }
  } catch (_) {}

  function applySession(s) {
    if (!s || !s.token) return false;
    let changed = false;
    try {
      if (localStorage.getItem("zeq_auth_token") !== s.token) { localStorage.setItem("zeq_auth_token", s.token); changed = true; }
      if (s.zid && localStorage.getItem("zeq_zid") !== s.zid) { localStorage.setItem("zeq_zid", s.zid); changed = true; }
      if (s.zidEmail && localStorage.getItem("zeq_zid_email") !== s.zidEmail) { localStorage.setItem("zeq_zid_email", s.zidEmail); }
    } catch (_) { return false; }
    return changed;
  }

  function clearSession() {
    // Extension is signed out → don't leave a stale token on the page.
    try {
      localStorage.removeItem("zeq_auth_token");
      localStorage.removeItem("zeq_zid");
      localStorage.removeItem("zeq_zid_email");
    } catch (_) {}
  }

  // Reload only ever makes sense for the TOP document. A nested iframe (an app
  // embedding another app — "iframe within an iframe") must NOT reload itself:
  // it causes the inner login flash the user saw, and can fight the parent.
  // Sub-frames instead get the token applied + re-applied on a short poll, so
  // they boot signed-in without a disruptive reload.
  const isTop = (() => { try { return window.top === window; } catch (_) { return false; } })();
  let _lastSession = null;

  function syncFromExtension(allowReload) {
    try {
      chrome.runtime.sendMessage({ type: "getSession" }, (res) => {
        if (chrome.runtime.lastError || !res) return;
        if (!res.token) { clearSession(); _lastSession = null; return; }
        _lastSession = res;
        const newlyWritten = applySession(res);
        // Top frame only: if the token wasn't present, the app rendered
        // logged-out before our async round-trip landed — reload ONCE so it
        // boots signed-in. Nested frames skip this (poll handles them).
        if (allowReload && isTop && newlyWritten && !sessionStorage.getItem(RELOAD_FLAG)) {
          try { sessionStorage.setItem(RELOAD_FLAG, "1"); } catch (_) {}
          location.reload();
        }
      });
    } catch (_) { /* not in extension context */ }
  }

  syncFromExtension(true);

  // Re-assert the token across the app's lifecycle: many apps render their auth
  // gate after our first write (SPA hydration), and nested/late iframes need the
  // token re-applied without a reload. Cheap idempotent writes (applySession
  // only touches localStorage when the value differs).
  function reassert() { if (_lastSession) applySession(_lastSession); }
  try { document.addEventListener("DOMContentLoaded", reassert); } catch (_) {}
  try { window.addEventListener("load", reassert); } catch (_) {}
  // Short poll for the first ~6s to cover late-mounting frames + SPA re-checks.
  let _polls = 0;
  const _pollTimer = setInterval(() => {
    if (_lastSession) applySession(_lastSession); else syncFromExtension(false);
    if (++_polls >= 12) clearInterval(_pollTimer); // 12 × 500ms = 6s
  }, 500);

  // Keep the page in sync if the extension logs in/out while it's open.
  try {
    chrome.runtime.onMessage.addListener((msg) => {
      if (msg && msg.type === "zeq_auth_event") {
        if (msg.payload && msg.payload.authenticated === false) { clearSession(); _lastSession = null; }
        else syncFromExtension(false);
      }
    });
  } catch (_) {}
})();
