/**
 * 认证状态管理 — React Context + Provider 模式。
 *
 * - 登录：调用 /api/tenant/auth/login，存储 token 到 localStorage
 * - 登出：清除 token，跳转 /login
 * - 用户信息：display_name, managed_site_ids（从 JWT payload 解析）
 */

import React, { createContext, useContext, useState, useCallback, useEffect } from "react";
import type { ReactNode } from "react";
import axios from "axios";

/* ------------------------------------------------------------------ */
/*  常量 & 类型                                                        */
/* ------------------------------------------------------------------ */

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

interface UserInfo {
  adminId: number;
  tenantId: number;
  displayName: string;
  managedSiteIds: number[];
  adminType: string;
}

interface AuthContextValue {
  isAuthenticated: boolean;
  user: UserInfo | null;
  login: (username: string, password: string) => Promise<void>;
  logout: () => void;
}

const AuthContext = createContext<AuthContextValue | null>(null);

/* ------------------------------------------------------------------ */
/*  JWT payload 解析（不做签名验证，仅提取信息）                        */
/* ------------------------------------------------------------------ */

function parseJwtPayload(token: string): Record<string, unknown> | null {
  try {
    const base64 = token.split(".")[1];
    const json = atob(base64.replace(/-/g, "+").replace(/_/g, "/"));
    return JSON.parse(json);
  } catch {
    return null;
  }
}

function extractUserInfo(token: string): UserInfo | null {
  const payload = parseJwtPayload(token);
  if (!payload) return null;
  return {
    adminId: Number(payload.sub),
    tenantId: Number(payload.tenant_id),
    displayName: String(payload.display_name ?? ""),
    managedSiteIds: Array.isArray(payload.managed_site_ids)
      ? (payload.managed_site_ids as number[])
      : [],
    adminType: String(payload.admin_type ?? "tenant_admin"),
  };
}

/* ------------------------------------------------------------------ */
/*  Provider                                                           */
/* ------------------------------------------------------------------ */

export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  const [user, setUser] = useState<UserInfo | null>(null);

  // 启动时从 localStorage 恢复登录状态
  useEffect(() => {
    const token = localStorage.getItem(ACCESS_TOKEN_KEY);
    if (token) {
      const info = extractUserInfo(token);
      if (info) setUser(info);
    }
  }, []);

  const login = useCallback(async (username: string, password: string) => {
    const { data } = await axios.post<{
      code: number;
      data: { access_token: string; refresh_token: string };
    }>("/api/tenant/auth/login", { username, password });

    const tokens = data.data;
    localStorage.setItem(ACCESS_TOKEN_KEY, tokens.access_token);
    localStorage.setItem(REFRESH_TOKEN_KEY, tokens.refresh_token);

    const info = extractUserInfo(tokens.access_token);
    setUser(info);
  }, []);

  const logout = useCallback(() => {
    localStorage.removeItem(ACCESS_TOKEN_KEY);
    localStorage.removeItem(REFRESH_TOKEN_KEY);
    setUser(null);
    if (window.location.pathname !== "/login") {
      window.location.href = "/login";
    }
  }, []);

  const value: AuthContextValue = {
    isAuthenticated: user !== null,
    user,
    login,
    logout,
  };

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};

/* ------------------------------------------------------------------ */
/*  Hook                                                               */
/* ------------------------------------------------------------------ */

export function useAuth(): AuthContextValue {
  const ctx = useContext(AuthContext);
  if (!ctx) {
    throw new Error("useAuth 必须在 AuthProvider 内使用");
  }
  return ctx;
}
