// 认证工具：token 存储（localStorage，F12 裁决）+ 登录（REST，ISSUE-004）
// 依据：02-architecture-design.md §4.1、F12 localStorage token、ISSUE-004 登录端点
// parent-portal 唯一走 REST 的端点：POST /api/v1/iam/login

import type { ActionState, LoginResponse, UserSession } from "@/types";

const TOKEN_KEY = "parent_access_token";
const REFRESH_TOKEN_KEY = "parent_refresh_token";
const USER_KEY = "parent_user_info";
const TOKEN_EXPIRES_KEY = "parent_token_expires_at";

/**
 * 获取 access token（SSR 安全）
 */
export function getToken(): string | null {
  if (typeof window === "undefined") return null;
  return localStorage.getItem(TOKEN_KEY);
}

/**
 * 获取 refresh token
 */
export function getRefreshToken(): string | null {
  if (typeof window === "undefined") return null;
  return localStorage.getItem(REFRESH_TOKEN_KEY);
}

/**
 * 设置 token（含过期时间）
 */
export function setTokens(
  accessToken: string,
  refreshToken: string,
  expiresIn: number,
): void {
  if (typeof window === "undefined") return;
  localStorage.setItem(TOKEN_KEY, accessToken);
  localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);
  const expiresAt = Date.now() + expiresIn * 1000;
  localStorage.setItem(TOKEN_EXPIRES_KEY, expiresAt.toString());
}

/**
 * 清除所有认证信息
 */
export function clearAuth(): void {
  if (typeof window === "undefined") return;
  localStorage.removeItem(TOKEN_KEY);
  localStorage.removeItem(REFRESH_TOKEN_KEY);
  localStorage.removeItem(USER_KEY);
  localStorage.removeItem(TOKEN_EXPIRES_KEY);
}

/**
 * 获取当前用户信息
 */
export function getUser(): UserSession | null {
  if (typeof window === "undefined") return null;
  const raw = localStorage.getItem(USER_KEY);
  if (!raw) return null;
  try {
    return JSON.parse(raw) as UserSession;
  } catch {
    return null;
  }
}

/**
 * 设置当前用户信息
 */
export function setUser(user: UserSession): void {
  if (typeof window === "undefined") return;
  localStorage.setItem(USER_KEY, JSON.stringify(user));
}

/**
 * 是否已认证（token 未过期）
 */
export function isAuthenticated(): boolean {
  if (typeof window === "undefined") return false;
  const token = getToken();
  if (!token) return false;
  const expiresAt = localStorage.getItem(TOKEN_EXPIRES_KEY);
  if (!expiresAt) return true; // 无过期时间视为永久
  return Date.now() < parseInt(expiresAt, 10);
}

/**
 * 登录（REST，ISSUE-004 唯一走 REST 的端点）
 * 调用 POST /api/v1/iam/login
 */
export async function login(
  email: string,
  password: string,
): Promise<{
  user: UserSession;
  tokens: { accessToken: string; refreshToken: string; expiresIn: number };
}> {
  const res = await fetch("/api/v1/iam/login", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Requested-With": "XMLHttpRequest",
    },
    body: JSON.stringify({ email, password }),
  });

  const json: ActionState<LoginResponse> = await res.json();

  if (!json.success) {
    throw new Error(json.error.message);
  }

  const { user, tokens } = json.data;
  setTokens(tokens.accessToken, tokens.refreshToken, tokens.expiresIn);
  setUser(user);
  return { user, tokens };
}

/**
 * 登出
 */
export function logout(): void {
  clearAuth();
  if (typeof window !== "undefined") {
    window.location.href = "/login";
  }
}

/**
 * Token 刷新（竞态防护：全局单例 promise 复用）
 */
let refreshPromise: Promise<string | null> | null = null;

export async function refreshAccessToken(): Promise<string | null> {
  // 复用进行中的 refresh 请求（避免多请求同时 401 触发多次 refresh）
  if (refreshPromise) return refreshPromise;

  const refreshToken = getRefreshToken();
  if (!refreshToken) {
    logout();
    return null;
  }

  refreshPromise = (async () => {
    try {
      const res = await fetch("/api/v1/iam/refresh", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-Requested-With": "XMLHttpRequest",
        },
        body: JSON.stringify({ refreshToken }),
      });

      if (!res.ok) {
        logout();
        return null;
      }

      const json: ActionState<{ tokens: LoginResponse["tokens"] }> =
        await res.json();
      if (!json.success) {
        logout();
        return null;
      }

      const {
        accessToken,
        refreshToken: newRefreshToken,
        expiresIn,
      } = json.data.tokens;
      setTokens(accessToken, newRefreshToken, expiresIn);
      return accessToken;
    } catch {
      logout();
      return null;
    } finally {
      refreshPromise = null;
    }
  })();

  return refreshPromise;
}

/**
 * 获取 Authorization header（供 GraphQL client 使用）
 */
export function getAuthHeaders(): Record<string, string> {
  const token = getToken();
  return token ? { Authorization: `Bearer ${token}` } : {};
}
