import { createContext, PropsWithChildren, useContext, useEffect, useState } from 'react'; import { SplashScreen, useRouter, useSegments } from 'expo-router'; import { UserData } from '@/types/types'; import * as SecureStore from 'expo-secure-store'; import api, { KEY_TOKEN } from './api'; type AuthState = { isAuthenticated: boolean; isReady: boolean; user: UserData | null; logIn: (token: string, userData: UserData) => void; logOut: () => void; }; SplashScreen.preventAutoHideAsync(); export const AuthContext = createContext({ isAuthenticated: false, isReady: false, user: null, logIn: () => { }, logOut: () => { }, }); export const useAuth = () => useContext(AuthContext); export function AuthProvider({ children }: PropsWithChildren) { const [isReady, setIsReady] = useState(false); const [isAuthenticated, setIsAuthenticated] = useState(false); const [user, setUser] = useState(null); const router = useRouter(); const segments = useSegments(); const logIn = async (token: string, userData: UserData) => { try { await SecureStore.setItemAsync(KEY_TOKEN, token); setIsAuthenticated(true); setUser(userData); router.replace('/'); } catch (error) { console.error('Errore durante il login:', error); } }; const logOut = async () => { try { await SecureStore.deleteItemAsync(KEY_TOKEN); setIsAuthenticated(false); setUser(null); router.replace('/login'); } catch (error) { console.error('Errore durante il logout:', error); } }; useEffect(() => { const initApp = async () => { try { // 1. Recupero Token salvato const savedToken = await SecureStore.getItemAsync(KEY_TOKEN); if (savedToken) { console.log("Token trovato: ", savedToken); // 2. Chiamata al backend per verificare il token e scaricare i dati utente // Nota: api.ts aggiunge già l'header Authorization grazie all'interceptor (se configurato per leggere da SecureStore) // Se il tuo api.ts legge da AsyncStorage, assicurati che siano allineati, altrimenti passalo a mano qui: const response = await api.get("/user/info", { headers: { Authorization: `Bearer ${savedToken}` } }); const result = response.data; const userData = result.user; console.log("Sessione valida, dati utente caricati:", userData); // 3. Mappatura dati (Backend -> Frontend) // Il backend actionMe ritorna: { id, username, role } const loadedUser: UserData = { id: userData.id, username: userData.username, role: userData.role, // Gestiamo i campi opzionali se il backend non li manda ancora name: userData.name, surname: userData.surname || '', email: userData.email || '', }; setUser(loadedUser); setIsAuthenticated(true); } else { console.log("Nessun token salvato."); } } catch (error: any) { console.error('Errore inizializzazione (Token scaduto o Server down):', error.message); // Se il token non è valido, puliamo tutto await SecureStore.deleteItemAsync(KEY_TOKEN); setIsAuthenticated(false); setUser(null); } finally { setIsReady(true); await SplashScreen.hideAsync(); } }; initApp(); }, []); // Protezione rotte (opzionale, ma consigliata qui o nel Layout) useEffect(() => { if (!isReady) return; const inAuthGroup = segments[0] === '(protected)'; if (!isAuthenticated && inAuthGroup) { router.replace('/login'); } else if (isAuthenticated && !inAuthGroup) { router.replace('/'); } }, [isReady, isAuthenticated, segments]); return ( {children} ); }