// Access token storage using sessionStorage for persistence across page refreshes
// sessionStorage is cleared when the tab/window is closed, providing reasonable security
// while avoiding unnecessary token refreshes on page reload
let accessToken: string | null = null;
let tokenExpiresAt: Date | null = null;
let refreshToken: string | null = null;

const SESSION_TOKEN_KEY = "memos_access_token";
const SESSION_EXPIRES_KEY = "memos_token_expires_at";
const SESSION_REFRESH_KEY = "memos_refresh_token";

export const getAccessToken = (): string | null => {
  // If not in memory, try to restore from sessionStorage
  if (!accessToken) {
    try {
      const storedToken = sessionStorage.getItem(SESSION_TOKEN_KEY);
      const storedExpires = sessionStorage.getItem(SESSION_EXPIRES_KEY);

      if (storedToken && storedExpires) {
        const expiresAt = new Date(storedExpires);
        // Only restore if token hasn't expired
        if (expiresAt > new Date()) {
          accessToken = storedToken;
          tokenExpiresAt = expiresAt;
        } else {
          // Token expired, clean up sessionStorage
          sessionStorage.removeItem(SESSION_TOKEN_KEY);
          sessionStorage.removeItem(SESSION_EXPIRES_KEY);
        }
      }
    } catch (e) {
      // sessionStorage might not be available (e.g., in some privacy modes)
      console.warn("Failed to access sessionStorage:", e);
    }
  }
  return accessToken;
};

export const getRefreshToken = (): string | null => {
  if (!refreshToken) {
    try {
      refreshToken = sessionStorage.getItem(SESSION_REFRESH_KEY);
    } catch (e) {
      console.warn("Failed to access sessionStorage:", e);
    }
  }
  return refreshToken;
};

export const hasRefreshToken = (): boolean => {
  return !!getRefreshToken();
};

export const setAccessToken = (token: string | null, expiresAt?: Date): void => {
  accessToken = token;
  tokenExpiresAt = expiresAt || null;

  try {
    if (token && expiresAt) {
      // Store in sessionStorage for persistence across page refreshes
      sessionStorage.setItem(SESSION_TOKEN_KEY, token);
      sessionStorage.setItem(SESSION_EXPIRES_KEY, expiresAt.toISOString());
    } else {
      // Clear sessionStorage if token is being cleared
      sessionStorage.removeItem(SESSION_TOKEN_KEY);
      sessionStorage.removeItem(SESSION_EXPIRES_KEY);
    }
  } catch (e) {
    // sessionStorage might not be available (e.g., in some privacy modes)
    console.warn("Failed to write to sessionStorage:", e);
  }
};

export const setRefreshToken = (token: string | null): void => {
  refreshToken = token;

  try {
    if (token) {
      sessionStorage.setItem(SESSION_REFRESH_KEY, token);
    } else {
      sessionStorage.removeItem(SESSION_REFRESH_KEY);
    }
  } catch (e) {
    console.warn("Failed to write to sessionStorage:", e);
  }
};

export const isTokenExpired = (): boolean => {
  if (!tokenExpiresAt) return true;
  // Consider expired 30 seconds before actual expiry for safety
  return new Date() >= new Date(tokenExpiresAt.getTime() - 30000);
};

export const clearAccessToken = (): void => {
  accessToken = null;
  tokenExpiresAt = null;
  refreshToken = null;

  try {
    sessionStorage.removeItem(SESSION_TOKEN_KEY);
    sessionStorage.removeItem(SESSION_EXPIRES_KEY);
    sessionStorage.removeItem(SESSION_REFRESH_KEY);
  } catch (e) {
    console.warn("Failed to clear sessionStorage:", e);
  }
};
