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<AuthState>({
    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<UserData | null>(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 {
                // Get saved Token from SecureStore
                const savedToken = await SecureStore.getItemAsync(KEY_TOKEN);

                if (savedToken) {
                    console.log("Token trovato: ", savedToken);

                    // Call backend to verify token and fetch user data
                    // Note: api.ts already adds the Authorization header thanks to the interceptor (if configured to read from SecureStore)
                    // If your api.ts reads from AsyncStorage, make sure they are aligned, otherwise pass it manually here:
                    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);

                    // Data mapping (Backend -> Frontend)
                    // The backend actionMe returns: { id, username, role }
                    const loadedUser: UserData = {
                        id: userData.id,
                        username: userData.username,
                        role: userData.role,
                        // Handle optional fields if the backend doesn't send them yet
                        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);

                // If the token is not valid, clear everything
                await SecureStore.deleteItemAsync(KEY_TOKEN);
                setIsAuthenticated(false);
                setUser(null);
            } finally {
                setIsReady(true);
                await SplashScreen.hideAsync();
            }
        };

        initApp();
    }, []);

    // Route protection (optional, but recommended here or in the 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 (
        <AuthContext.Provider value={{ isReady, isAuthenticated, user, logIn, logOut }}>
            {children}
        </AuthContext.Provider>
    );
}