import type { AuthSessionResponse } from "./contractsAuth";

const STORAGE_KEY = "space-game.auth.session";

export interface AuthSession {
  userId: string;
  email: string;
  roles: string[];
  accessToken: string;
  accessTokenExpiresAtUtc: string;
  refreshToken: string;
  refreshTokenExpiresAtUtc: string;
}

let currentSession: AuthSession | null = loadStoredSession();
const listeners = new Set<(session: AuthSession | null) => void>();

export function getAuthSession(): AuthSession | null {
  return currentSession;
}

export function setAuthSession(session: AuthSessionResponse | null) {
  currentSession = session ? { ...session } : null;
  persistSession(currentSession);
  notifyListeners();
}

export function clearAuthSession() {
  currentSession = null;
  persistSession(null);
  notifyListeners();
}

export function subscribeToAuthSession(listener: (session: AuthSession | null) => void) {
  listeners.add(listener);
  return () => listeners.delete(listener);
}

function loadStoredSession(): AuthSession | null {
  if (typeof window === "undefined") {
    return null;
  }

  const raw = window.localStorage.getItem(STORAGE_KEY);
  if (!raw) {
    return null;
  }

  try {
    const parsed = JSON.parse(raw) as AuthSession;
    return parsed?.accessToken && parsed?.refreshToken
      ? { ...parsed, roles: Array.isArray(parsed.roles) ? parsed.roles : [] }
      : null;
  } catch {
    return null;
  }
}

function persistSession(session: AuthSession | null) {
  if (typeof window === "undefined") {
    return;
  }

  if (!session) {
    window.localStorage.removeItem(STORAGE_KEY);
    return;
  }

  window.localStorage.setItem(STORAGE_KEY, JSON.stringify(session));
}

function notifyListeners() {
  for (const listener of listeners) {
    listener(currentSession);
  }
}
