import { useState, useEffect, createContext } from "react";
import createAxiosInstance from "@/api/axiosInstance";
import { useConfig } from "@/hooks/useConfig";

export const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const axios = createAxiosInstance();
  const { config } = useConfig();

  const [token, setToken] = useState(() => localStorage.getItem("token"));
  const [identity, setIdentity] = useState(() => {
    const stored = localStorage.getItem("identity");
    return stored ? JSON.parse(stored) : null;
  });

  const [authStatus, setAuthStatus] = useState("checking");
  const [error, setError] = useState(null);

  useEffect(() => {
    if (!config) return;

    if (!token) {
      setAuthStatus("unauthenticated");
      return;
    }

    const BASE_URL = config.apiConfig.baseUrl;
    const VALIDATE_URL = `${BASE_URL}${config.apiConfig.endpoints.auth.validateToken}`;

    const checkAuth = async () => {
      try {
        const res = await axios.get(VALIDATE_URL, {
          headers: { Authorization: `Bearer ${token}` },
        });

        if (res.status === 200) {
          setAuthStatus("authenticated");
        } else {
          logout();
        }
      } catch (err) {
        console.error("Error validando token:", err);
        logout();
      }
    };

    checkAuth();
  }, [token, config]);

  const login = async (formData) => {
    setError(null);

    const BASE_URL = config.apiConfig.baseUrl;
    const LOGIN_URL = `${BASE_URL}${config.apiConfig.endpoints.auth.login}`;

    try {
      const res = await axios.post(LOGIN_URL, formData);

      const { token, user, account, metadata } = res.data;

      const identity = {
        user,
        account,
        metadata,
      };

      localStorage.setItem("token", token);
      localStorage.setItem("identity", JSON.stringify(identity));

      setToken(token);
      setIdentity(identity);
      setAuthStatus("authenticated");
    } catch (err) {
      console.error("Error al iniciar sesión:", err);

      let message = "Ha ocurrido un error inesperado.";

      if (err.response) {
        const { status, data } = err.response;

        if (status === 400) {
          message = "Usuario o contraseña incorrectos.";
        } else if (status === 403) {
          message = "Tu cuenta está inactiva o suspendida.";
        } else if (status === 404) {
          message = "Usuario no encontrado.";
        } else if (data?.message) {
          message = data.message;
        }
      }

      setError(message);
      throw new Error(message);
    }
  };

  const register = async (formData) => {
    setError(null);

    const BASE_URL = config.apiConfig.baseUrl;
    const REGISTER_URL = `${BASE_URL}${config.apiConfig.endpoints.auth.register}`;

    try {
      const res = await axios.post(REGISTER_URL, formData);

      const { token, user, account, metadata } = res.data;

      const identity = {
        user,
        account,
        metadata,
      };

      localStorage.setItem("token", token);
      localStorage.setItem("identity", JSON.stringify(identity));

      setToken(token);
      setIdentity(identity);
      setAuthStatus("authenticated");
    } catch (err) {
      console.error("Error al registrarse:", err);

      let message = "Ha ocurrido un error inesperado.";

      if (err.response) {
        const { status, data } = err.response;

        if (status === 400) {
          message = "Usuario o contraseña incorrectos.";
        } else if (status === 403) {
          message = "Tu cuenta está inactiva o suspendida.";
        } else if (status === 404) {
          message = "Usuario no encontrado.";
        } else if (data?.message) {
          message = data.message;
        }
      }

      setError(message);
      throw new Error(message);
    }
  };

  const logout = () => {
    localStorage.removeItem("token");
    localStorage.removeItem("identity");
    setIdentity(null);
    setToken(null);
    setAuthStatus("unauthenticated");
  };

  const clearError = () => setError(null);

  return (
    <AuthContext.Provider
      value={{
        identity,        // { user, account, metadata }
        token,
        authStatus,
        login,
        register,
        logout,
        error,
        clearError
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};
