"use client"; import React, { createContext, useContext, useEffect, useState } from "react"; import { onAuthStateChanged, User as FirebaseUser, signOut } from "firebase/auth"; import { ref, get, update } from "firebase/database"; import { auth, db } from "@/lib/firebase"; import { RestaurantUser } from "@/types/user"; import { useRouter } from "next/navigation"; interface AuthContextType { user: RestaurantUser | null; firebaseUser: FirebaseUser | null; loading: boolean; logout: () => Promise; updateRestaurantProfile: (updates: Partial) => Promise<{ success: boolean; error?: any }>; } const AuthContext = createContext({ user: null, firebaseUser: null, loading: true, logout: async () => {}, updateRestaurantProfile: async () => ({ success: false }), }); export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const router = useRouter(); const [user, setUser] = useState(null); const [firebaseUser, setFirebaseUser] = useState(null); const [loading, setLoading] = useState(true); const buildDocumentId = (email: string) => { return email.replace(/\./g, "_").replace(/@/g, "_at_"); }; // Search for user by UID across all Restaurantes documents const findUserByUid = async (uid: string, currentUser: FirebaseUser): Promise => { try { const restaurantsRef = ref(db, "Restaurantes"); const snapshot = await get(restaurantsRef); if (!snapshot.exists()) return null; const data = snapshot.val(); for (const key of Object.keys(data)) { const item = data[key]; if (item?.uid === uid) { return { ...item, email: item.email || currentUser.email } as RestaurantUser; } } } catch (error) { console.error("[Auth] Error searching by UID:", error); } return null; }; // Search for user by email across all Restaurantes documents const findUserByEmail = async (email: string): Promise => { try { const restaurantsRef = ref(db, "Restaurantes"); const snapshot = await get(restaurantsRef); if (!snapshot.exists()) return null; const data = snapshot.val(); for (const key of Object.keys(data)) { const item = data[key]; if (item?.email === email || item?.establishmentEmail === email || item?.ownerEmail === email) { return { ...item, email: item.email || email } as RestaurantUser; } } } catch (error) { console.error("[Auth] Error searching by email:", error); } return null; }; useEffect(() => { const unsubscribe = onAuthStateChanged(auth, async (currentUser) => { try { if (currentUser && currentUser.email) { setFirebaseUser(currentUser); let data: RestaurantUser | null = null; // Strategy 1: Try building document ID from email (website format) const docId = buildDocumentId(currentUser.email); const userRef = ref(db, `Restaurantes/${docId}`); let snapshot = await get(userRef); if (snapshot.exists()) { data = snapshot.val() as RestaurantUser; } // Strategy 2: Try with original email as document ID (Android format) if (!data) { const originalRef = ref(db, `Restaurantes/${currentUser.email}`); snapshot = await get(originalRef); if (snapshot.exists()) { data = snapshot.val() as RestaurantUser; } } // Strategy 3: Search all Restaurantes documents by UID if (!data && currentUser.uid) { data = await findUserByUid(currentUser.uid, currentUser); } // Strategy 4: Search all Restaurantes documents by email if (!data) { data = await findUserByEmail(currentUser.email); } if (data) { if (data.accountType === "ESTABELECIMENTO") { setUser(data); } else { console.warn("[Auth] User is not a restaurant account type:", data.accountType); setUser(null); await signOut(auth); } } else { // User exists in Auth but not in database — possible orphaned account console.warn("[Auth] User record not found in Restaurantes for:", currentUser.email); console.warn("[Auth] UID:", currentUser.uid); setUser(null); } } else { // No Firebase user — clear state setFirebaseUser(null); setUser(null); } } catch (error) { console.error("[Auth] Error in onAuthStateChanged:", error); // On error, clear user state to prevent broken state setUser(null); setFirebaseUser(null); } finally { setLoading(false); } }); return () => unsubscribe(); }, []); const logout = async () => { try { await signOut(auth); router.push("/login"); } catch (error) { console.error("Erro ao fazer logout:", error); } }; const updateRestaurantProfile = async (updates: Partial) => { if (!firebaseUser?.email) return { success: false, error: "Utilizador não autenticado" }; try { const docId = buildDocumentId(firebaseUser.email); const userRef = ref(db, `Restaurantes/${docId}`); await update(userRef, updates); setUser(prev => prev ? { ...prev, ...updates } : null); return { success: true }; } catch (error) { console.error("Erro ao atualizar perfil:", error); return { success: false, error }; } }; return ( {children} ); }; export const useAuth = () => useContext(AuthContext);