/**
 * 认证状态管理 — Zustand store。
 *
 * - 存储 JWT 令牌和用户信息
 * - login / logout / hydrate 三个核心方法
 * - 令牌同步到 localStorage，与 client.ts 拦截器共用同一 key
 */

import { create } from "zustand";
import { apiClient } from "../api/client";

/* ------------------------------------------------------------------ */
/*  类型                                                               */
/* ------------------------------------------------------------------ */

/** 当前登录用户信息（从 JWT payload 解码或登录响应中获取） */
export interface AuthUser {
  user_id: number;
  username: string;
  display_name: string;
  site_id: number;
  roles: string[];
}

/** 后端 /api/auth/login 响应体 */
interface LoginResponse {
  access_token: string;
  refresh_token: string;
  token_type: string;
}

export interface AuthState {
  accessToken: string | null;
  refreshToken: string | null;
  user: AuthUser | null;
  isAuthenticated: boolean;

  /** 用户名密码登录，成功后存储令牌到 state 和 localStorage */
  login: (username: string, password: string) => Promise<void>;
  /** 登出，清除 state 和 localStorage */
  logout: () => void;
  /** 从 localStorage 恢复状态（应用启动时调用） */
  hydrate: () => void;
}

/* ------------------------------------------------------------------ */
/*  常量 — 与 client.ts 保持一致                                       */
/* ------------------------------------------------------------------ */

const ACCESS_TOKEN_KEY = "access_token";
const REFRESH_TOKEN_KEY = "refresh_token";

/* ------------------------------------------------------------------ */
/*  辅助：从 JWT payload 解析用户信息                                   */
/* ------------------------------------------------------------------ */

function parseJwtPayload(token: string): AuthUser | null {
  try {
    const base64 = token.split(".")[1];
    if (!base64) return null;
    const json = atob(base64);
    const payload = JSON.parse(json) as Record<string, unknown>;
    return {
      user_id: payload.user_id as number,
      username: payload.username as string,
      display_name: (payload.display_name as string) ?? "",
      site_id: payload.site_id as number,
      roles: (payload.roles as string[]) ?? [],
    };
  } catch {
    return null;
  }
}

/* ------------------------------------------------------------------ */
/*  Store                                                              */
/* ------------------------------------------------------------------ */

export const useAuthStore = create<AuthState>((set, _get) => ({
  accessToken: null,
  refreshToken: null,
  user: null,
  isAuthenticated: false,

  async login(username: string, password: string) {
    const { data } = await apiClient.post<LoginResponse>("/auth/login", {
      username,
      password,
    });

    const { access_token, refresh_token } = data;

    // 持久化到 localStorage
    localStorage.setItem(ACCESS_TOKEN_KEY, access_token);
    localStorage.setItem(REFRESH_TOKEN_KEY, refresh_token);

    const user = parseJwtPayload(access_token);

    set({
      accessToken: access_token,
      refreshToken: refresh_token,
      user,
      isAuthenticated: true,
    });
  },

  logout() {
    localStorage.removeItem(ACCESS_TOKEN_KEY);
    localStorage.removeItem(REFRESH_TOKEN_KEY);

    set({
      accessToken: null,
      refreshToken: null,
      user: null,
      isAuthenticated: false,
    });
  },

  hydrate() {
    const accessToken = localStorage.getItem(ACCESS_TOKEN_KEY);
    const refreshToken = localStorage.getItem(REFRESH_TOKEN_KEY);

    if (accessToken) {
      const user = parseJwtPayload(accessToken);
      set({
        accessToken,
        refreshToken,
        user,
        isAuthenticated: true,
      });
    }
  },
}));

// 监听 axios 拦截器的强制登出事件，同步清除 Zustand 状态
// 避免 localStorage 已清空但 isAuthenticated 仍为 true 导致白屏
window.addEventListener("auth:force-logout", () => {
  useAuthStore.getState().logout();
});
