import React, {
  createContext,
  useContext,
  useState,
  useEffect,
  useCallback,
} from "react";
import { userLogin, registerUser, logoutUser } from "@/api/auth";
import { message } from "antd";
import { useNavigate } from "react-router-dom"; // 导入 useNavigate

const AuthContext = createContext(null);

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true); // 初始加载状态
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const navigate = useNavigate();

  const loadAuthData = useCallback(() => {
    setLoading(true);
    try {
      const storedToken = localStorage.getItem("token");
      const storedUser = localStorage.getItem("user");

      console.log("Loading auth data - token:", !!storedToken, "user:", !!storedUser);

      if (storedToken && storedUser) {
        try {
          const userData = JSON.parse(storedUser);
          // console.log("Parsed user data:", userData);
          setUser(userData);
          setIsAuthenticated(true);
        } catch (parseError) {
          console.error("Failed to parse stored user data:", parseError);
          // 如果解析失败，清除损坏的数据
          localStorage.removeItem("token");
          localStorage.removeItem("user");
          setIsAuthenticated(false);
          setUser(null);
        }
      } else {
        console.log("No stored auth data found");
        setIsAuthenticated(false);
        setUser(null);
      }
    } catch (error) {
      console.error("Failed to load auth data from storage", error);
      setIsAuthenticated(false);
      setUser(null);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    loadAuthData();
  }, [loadAuthData]);

  const login = async (params) => {
    setLoading(true);
    try {
      const response = await userLogin(params);
      // 检查响应是否成功
      if (response && response.data) {
        const token = response.data.token;
        const userData = response.data;
        
        console.log("Saving token:", token);
        console.log("Saving user data:", userData);
        
        localStorage.setItem("token", token);
        localStorage.setItem("user", JSON.stringify(userData));
        
        setUser(userData);
        setIsAuthenticated(true);
        
        message.success(response?.message || "登录成功");
        return userData;
      }
    } catch (error) {
      console.log("login error", error);
      setIsAuthenticated(false);
      setUser(null);
      message.error(error.message || "登录失败，请检查用户名和密码");
    } finally {
      setLoading(false);
    }
  };

  const register = async (userData) => {
    setLoading(true);
    try {
      const response = await registerUser(userData);

      // 检查响应是否成功
      if (response.data && response.data.success) {
        const { token, user: newUser } = response.data.data;

        localStorage.setItem("token", token);
        localStorage.setItem("user", JSON.stringify(newUser));
        setUser(newUser);
        setIsAuthenticated(true);
        message.success("注册成功");
        return newUser;
      } else {
        throw new Error(response.data?.message || "注册失败");
      }
    } catch (error) {
      console.error("Registration failed", error);
      message.error(error.message || "注册失败，请稍后再试");
    } finally {
      setLoading(false);
    }
  };

  const logout = async () => {
    try {
      await logoutUser();
      localStorage.removeItem("token");
      localStorage.removeItem("user");
      localStorage.removeItem("permissions"); // 移除旧的权限存储
      setUser(null);
      setIsAuthenticated(false);
      message.success("已成功退出登录");
      navigate("/login");
      return true;
    } catch (error) {
      console.error("登出失败", error);
      message.error("登出失败");
      return false;
    }
  };

  const hasRole = useCallback(
    (roleName) => {
      return user?.role === roleName;
    },
    [user]
  );

  const value = {
    user,
    isAuthenticated,
    loading,
    login,
    register,
    logout,
    hasRole,
    reloadAuthData: loadAuthData, // 暴露一个重新加载数据的方法
  };

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

export const useAuth = () => {
  const context = useContext(AuthContext);
  if (context === undefined || context === null) {
    // 增加了对 null 的检查
    throw new Error("useAuth must be used within an AuthProvider");
  }
  return context;
};
