// clerk.jsx — loads Clerk's hosted browser SDK (no build step) and exposes a
// tiny session facade on window.MC_CLERK. Loaded before app.jsx. The
// publishable key is fetched from /api/config at runtime, so it is never
// hard-coded here.

const CLERK_SRC =
  "https://cdn.jsdelivr.net/npm/@clerk/clerk-js@5/dist/clerk.browser.js";

let _clerkPromise = null;

function _loadScript(src, publishableKey) {
  return new Promise((resolve, reject) => {
    const existing = document.querySelector("script[data-clerk-sdk]");
    if (existing) {
      // If a prior load failed (e.g. missing key), drop the dead tag so the
      // retry can attach the attribute and re-run the SDK's auto-init.
      if (!window.Clerk) existing.remove();
      else { resolve(); return; }
    }
    const s = document.createElement("script");
    s.src = src;
    s.async = true;
    s.crossOrigin = "anonymous";
    s.setAttribute("data-clerk-sdk", "1");
    // clerk.browser.js auto-initialises on load and reads the publishable
    // key from this attribute on its own <script> element — it MUST be set
    // before append, otherwise the SDK throws "Missing publishableKey".
    if (publishableKey) s.setAttribute("data-clerk-publishable-key", publishableKey);
    s.onload = () => resolve();
    s.onerror = () => reject(new Error("Failed to load the Clerk SDK"));
    document.head.appendChild(s);
  });
}

// Idempotent: loads the SDK once (with publishable key attached so its
// auto-init succeeds), runs Clerk.load(), and caches the promise.
async function ensure(publishableKey) {
  if (_clerkPromise) return _clerkPromise;
  _clerkPromise = (async () => {
    await _loadScript(CLERK_SRC, publishableKey);
    const C = window.Clerk;
    if (!C) throw new Error("Clerk global missing after SDK load");
    // After auto-init with the data attribute, window.Clerk is a pre-built
    // singleton; if it ever ships as a class, fall back to constructing it.
    const clerk = typeof C === "function" ? new C(publishableKey) : C;
    if (typeof clerk.load === "function") await clerk.load();
    window.__mcClerk = clerk;
    return clerk;
  })();
  return _clerkPromise;
}

window.MC_CLERK = {
  ensure,
  get: () => window.__mcClerk || null,
  user: () => (window.__mcClerk ? window.__mcClerk.user : null),
  onChange: (cb) =>
    (window.__mcClerk ? window.__mcClerk.addListener(cb) : () => {}),
  getToken: async () => {
    const c = window.__mcClerk;
    if (!c || !c.session) return null;
    try { return await c.session.getToken(); } catch { return null; }
  },
  signOut: async () => { if (window.__mcClerk) await window.__mcClerk.signOut(); },
  mountSignIn: (el, opts) => window.__mcClerk && window.__mcClerk.mountSignIn(el, opts || {}),
  mountSignUp: (el, opts) => window.__mcClerk && window.__mcClerk.mountSignUp(el, opts || {}),
  mountUserButton: (el, opts) =>
    window.__mcClerk && window.__mcClerk.mountUserButton(el, opts || {}),
};
