import React, { createContext, useContext, useState, useEffect } from "react"; import { signInWithPopup, signOut as firebaseSignOut } from "firebase/auth"; import { auth, googleProvider } from "@/config/firebase"; import { getCurrentUser, firebaseLogin, requestOTP, verifyOTP, logout as apiLogout } from "@/services/auth"; const AuthContext = createContext(null); export function AuthProvider({ children }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [token, setToken] = useState(localStorage.getItem("auth_token")); useEffect(() => { // Check if user is already authenticated if (token) { checkAuth(); } else { setLoading(false); } }, [token]); const checkAuth = async () => { try { const userData = await getCurrentUser(); setUser(userData); } catch (error) { // Token is invalid, clear it localStorage.removeItem("auth_token"); setToken(null); setUser(null); } finally { setLoading(false); } }; const handleFirebaseLogin = async () => { try { const result = await signInWithPopup(auth, googleProvider); const idToken = await result.user.getIdToken(); const response = await firebaseLogin(idToken); handleAuthCallback(response.token); } catch (error) { if (error.code === 'auth/popup-closed' || error.code === 'auth/cancelled-popup-request') { // User closed popup or cancelled - don't show error return; } console.error("Firebase login error:", error); throw new Error(error.message || "Firebase authentication failed"); } }; const handleOTPRequest = async (email) => { try { await requestOTP(email); } catch (error) { console.error("OTP request error:", error); throw error; } }; const handleOTPVerify = async (email, otp) => { try { const response = await verifyOTP(email, otp); handleAuthCallback(response.token); } catch (error) { console.error("OTP verify error:", error); throw error; } }; const handleLogout = async () => { try { // Sign out from Firebase if user was using Firebase auth if (auth.currentUser) { await firebaseSignOut(auth); } await apiLogout(); } catch (error) { console.error("Logout error:", error); } finally { localStorage.removeItem("auth_token"); setToken(null); setUser(null); } }; const handleAuthCallback = (newToken) => { localStorage.setItem("auth_token", newToken); setToken(newToken); checkAuth(); }; const value = { user, token, loading, firebaseLogin: handleFirebaseLogin, requestOTP: handleOTPRequest, verifyOTP: handleOTPVerify, logout: handleLogout, handleAuthCallback, isAuthenticated: !!user, }; return {children}; } export function useAuth() { const context = useContext(AuthContext); if (!context) { throw new Error("useAuth must be used within an AuthProvider"); } return context; }