import React, { createContext, useContext, useState, useEffect } from 'react';
import axios from 'axios';

const AuthContext = createContext();

export const useAuth = () => useContext(AuthContext);

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  const API_URL = import.meta.env.VITE_API_URL;

  // Keep HF Space alive — ping every 25 minutes to prevent sleeping
  useEffect(() => {
    const ping = () => axios.get(`${API_URL}/users`).catch(() => {});
    ping(); // initial ping on load
    const interval = setInterval(ping, 25 * 60 * 1000);
    return () => clearInterval(interval);
  }, []);

  useEffect(() => {
    const initializeAuth = async () => {
      console.log('[Auth] Initializing authentication...');
      const token = localStorage.getItem('token');
      if (token) {
        console.log('[Auth] Found token in localStorage, setting Authorization header.');
        axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
        try {
          console.log('[Auth] Fetching user profile from:', `${API_URL}/users/me`);
          const response = await axios.get(`${API_URL}/users/me`);
          console.log('[Auth] Profile fetched successfully:', response.data);
          setUser(response.data);
        } catch (error) {
          console.error('[Auth] Failed to fetch profile:', error);
          // Only logout on explicit authorization failures (e.g. 401, 403). Keep session on server network errors.
          if (error.response && (error.response.status === 401 || error.response.status === 403 || error.response.status === 404)) {
            console.warn('[Auth] Token is expired, invalid, or user was not found on server. Logging out.');
            logout();
          } else {
            console.warn('[Auth] Server is unreachable or returned network error. Retaining session.');
            const cachedUser = localStorage.getItem('user');
            if (cachedUser) {
              try {
                const parsed = JSON.parse(cachedUser);
                console.log('[Auth] Loaded cached user from localStorage:', parsed);
                setUser(parsed);
              } catch (parseErr) {
                console.error('[Auth] Failed to parse cached user:', parseErr);
                logout();
              }
            }
          }
        }
      } else {
        console.log('[Auth] No token found in localStorage.');
      }
      setLoading(false);
    };

    initializeAuth();
  }, []);

  const login = async (email, password) => {
    try {
      const response = await axios.post(`${API_URL}/users/login`, { email, password });
      handleAuthResponse(response.data);
      return { success: true };
    } catch (error) {
      return { success: false, message: error.response?.data?.message || 'Login failed' };
    }
  };

  const register = async (email, password, displayName) => {
    try {
      const response = await axios.post(`${API_URL}/users/register`, { email, password, displayName });
      handleAuthResponse(response.data);
      return { success: true };
    } catch (error) {
      return { success: false, message: error.response?.data?.message || 'Registration failed' };
    }
  };

  const googleLogin = async (idToken) => {
    try {
      const response = await axios.post(`${API_URL}/users/google-login`, { idToken });
      handleAuthResponse(response.data);
      return { success: true };
    } catch (error) {
      return { success: false, message: error.response?.data?.message || 'Google Login failed' };
    }
  };

  const logout = () => {
    setUser(null);
    localStorage.removeItem('user');
    localStorage.removeItem('token');
    delete axios.defaults.headers.common['Authorization'];
  };

  const updateUser = (updatedUser) => {
    setUser(updatedUser);
    localStorage.setItem('user', JSON.stringify(updatedUser));
  };

  const handleAuthResponse = (data) => {
    const { user, token } = data;
    setUser(user);
    localStorage.setItem('user', JSON.stringify(user));
    localStorage.setItem('token', token);
    axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
  };

  return (
    <AuthContext.Provider value={{ user, loading, login, register, googleLogin, logout, updateUser }}>
      {!loading && children}
    </AuthContext.Provider>
  );
};
