// auth.jsx — Clerk bootstrap + authenticated API helper for the static app.
(function () {
  const state = {
    ready: false,
    signedIn: false,
    user: null,
    features: {},
    error: null
  };

  function emit() {
    window.dispatchEvent(new CustomEvent('astro-auth', { detail: { ...state } }));
  }

  function clerkDomain(publishableKey) {
    try {
      return atob(publishableKey.split('_')[2]).slice(0, -1);
    } catch {
      return null;
    }
  }

  function loadScript(src, attrs = {}) {
    return new Promise((resolve, reject) => {
      const existing = document.querySelector(`script[src="${src}"]`);
      if (existing) {
        existing.addEventListener('load', resolve, { once: true });
        existing.addEventListener('error', reject, { once: true });
        return;
      }
      const script = document.createElement('script');
      script.src = src;
      script.async = true;
      script.crossOrigin = 'anonymous';
      Object.entries(attrs).forEach(([k, v]) => script.setAttribute(k, v));
      script.onload = resolve;
      script.onerror = () => reject(new Error(`Failed to load ${src}`));
      document.head.appendChild(script);
    });
  }

  async function init() {
    try {
      const configRes = await fetch('/api/config', { headers: { accept: 'application/json' } });
      const config = await configRes.json();
      state.features = config.features || {};

      if (!config.clerkPublishableKey) {
        state.ready = true;
        state.error = 'Clerk publishable key is not configured';
        emit();
        return state;
      }

      const domain = clerkDomain(config.clerkPublishableKey);
      if (!domain) throw new Error('Invalid Clerk publishable key');

      await loadScript(`https://${domain}/npm/@clerk/ui@1/dist/ui.browser.js`);
      await loadScript(`https://${domain}/npm/@clerk/clerk-js@6/dist/clerk.browser.js`, {
        'data-clerk-publishable-key': config.clerkPublishableKey
      });

      await window.Clerk.load({ ui: { ClerkUI: window.__internal_ClerkUICtor } });
      state.ready = true;
      state.signedIn = Boolean(window.Clerk.isSignedIn);
      state.user = window.Clerk.user || null;
      emit();

      if (window.Clerk.addListener) {
        window.Clerk.addListener(({ user }) => {
          state.ready = true;
          state.signedIn = Boolean(user);
          state.user = user || null;
          emit();
        });
      }

      return state;
    } catch (err) {
      state.ready = true;
      state.error = err.message || 'Authentication failed to initialize';
      emit();
      return state;
    }
  }

  async function getToken() {
    if (!window.Clerk) return null;
    await window.Clerk.load();
    return window.Clerk.session ? window.Clerk.session.getToken() : null;
  }

  async function authorizedFetch(input, init = {}) {
    const token = await getToken();
    const headers = new Headers(init.headers || {});
    headers.set('accept', headers.get('accept') || 'application/json');
    if (token) headers.set('authorization', `Bearer ${token}`);
    return fetch(input, { ...init, headers });
  }

  function signIn() {
    if (window.Clerk) window.Clerk.openSignIn();
  }

  function signUp() {
    if (window.Clerk) window.Clerk.openSignUp();
  }

  function signOut() {
    if (window.Clerk) window.Clerk.signOut();
  }

  function mountUserButton(el) {
    if (window.Clerk && el && state.signedIn) window.Clerk.mountUserButton(el);
  }

  window.AstroAuth = {
    state,
    init,
    getToken,
    fetch: authorizedFetch,
    signIn,
    signUp,
    signOut,
    mountUserButton
  };

  init();
})();
