// @File: src/lib/auth-guard.ts
// @Desc: Neutralises two @metagptx/web-sdk behaviours that otherwise bounce our
//        standalone WHMCS login users back to the Atoms OIDC flow:
//
//        1. The SDK installs a `message` listener that accepts a
//           `mgx-token-saved` event from the parent Atoms frame, calls
//           `/api/v1/auth/token/exchange`, writes the returned Atoms-OIDC token
//           into `localStorage.token`, and reloads the page to `/`. This steals
//           the session away from a user who signed in via /login.
//
//        2. The SDK's HTTP client, on a 401, redirects `window.location` to
//           `/api/v1/auth/login?from_url=...` (the Atoms OIDC entry point).
//           We don't call that path any more, but we still defend against it.
//
//        The guard works by installing an EARLY capturing listener that
//        stops propagation of `mgx-token-saved` messages whenever our own
//        standalone session already owns `localStorage.token`. We never touch
//        the parent-frame messaging API itself.
//
//        Import this module EXACTLY ONCE, as early as possible (main.tsx).

const MANUAL_LOGOUT_KEY = "isLougOutManual";
const TOKEN_KEY = "token";

function hasOurToken(): boolean {
  try {
    const t = window.localStorage.getItem(TOKEN_KEY);
    return !!t && t.length > 0;
  } catch {
    return false;
  }
}

function manuallyLoggedOut(): boolean {
  try {
    return window.localStorage.getItem(MANUAL_LOGOUT_KEY) === "true";
  } catch {
    return false;
  }
}

export function installAuthGuard(): void {
  if (typeof window === "undefined") return;

  // Capture-phase listener runs BEFORE the SDK's own bubble-phase listener,
  // so stopping propagation here prevents the SDK from exchanging / replacing
  // our token.
  window.addEventListener(
    "message",
    (event: MessageEvent) => {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const data: any = event?.data;
      if (!data || typeof data !== "object") return;

      if (data.type === "mgx-token-saved") {
        // Block the parent-frame token handoff whenever the current browser
        // already has its own session, OR the user has explicitly signed out
        // of our app. We never want Atoms OIDC to silently re-authenticate
        // the user behind their back.
        if (hasOurToken() || manuallyLoggedOut()) {
          event.stopImmediatePropagation();
          event.stopPropagation();
        }
      }
    },
    true, // capture
  );
}