import { createContext, PropsWithChildren, useContext, useEffect, useState } from 'react';
import { SplashScreen, useRouter, useSegments } from 'expo-router';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { UserData } from '@/types/types';
import * as SecureStore from 'expo-secure-store';
import api, { GATEWAY_ENDPOINT, GATEWAY_TOKEN } from './api';
import axios from 'axios';

type AuthState = {
    isAuthenticated: boolean;
    isReady: boolean;
    user: UserData | null;
    logIn: (token: string, userData: UserData) => void;
    logOut: () => void;
};

SplashScreen.preventAutoHideAsync();

const KEY_TOKEN = 'auth-token';
const KEY_URL = 'App_URL';

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 storeAuthState = async (newState: { isAuthenticated: boolean }) => {
        try {
            const jsonValue = JSON.stringify(newState);
            await AsyncStorage.setItem(KEY_TOKEN, jsonValue);
        } catch (error) {
            console.error('Errore nel salvataggio dello stato di autenticazione:', error);
        }
    }

    const logIn = async (token: string, userData: UserData) => {
        try {
            await SecureStore.setItemAsync(KEY_TOKEN, token);
            setIsAuthenticated(true);
            setUser(userData);
            storeAuthState({ isAuthenticated: true }); // TODO: can be removed later
            router.replace('/');
        } catch (error) {
            console.error('Errore durante il login:', error);
        }
    };

    const logOut = async () => {
        try {
            await SecureStore.deleteItemAsync(KEY_TOKEN);
            setIsAuthenticated(false);
            setUser(null);
            storeAuthState({ isAuthenticated: false });
            router.replace('/login');
        } catch (error) {
            console.error('Errore durante il logout:', error);
        }
    };

    useEffect(() => {
        const initApp = async () => {
            try {
                // 1. Gestione URL Gateway (Logica "else" del vecchio snippet)
                let currentApiUrl = await SecureStore.getItemAsync(KEY_URL);

                if (!currentApiUrl) {
                    console.log("URL non trovato, contatto Gateway...");
                    try {
                        // Chiamata diretta al gateway (senza interceptor api.ts)
                        const gwResponse = await axios.get(GATEWAY_ENDPOINT, {
                            headers: { "x-access-tokens": GATEWAY_TOKEN }
                        });

                        // Supponiamo che il backend ritorni { url: "http://..." }
                        // Adatta questo parsing alla risposta reale del tuo backend
                        const newUrl = gwResponse.data.url + "/api/app_cantieri";

                        await SecureStore.setItemAsync(KEY_URL, newUrl);
                        currentApiUrl = newUrl;
                        console.log("URL acquisito:", newUrl);
                    } catch (gwError) {
                        console.error("Errore connessione Gateway:", gwError);
                        // Qui potresti decidere di non bloccare l'app o mostrare un errore
                    }
                }

                // 2. Controllo Token e Recupero User (Logica "if" del vecchio snippet)
                const savedToken = await SecureStore.getItemAsync(KEY_TOKEN);

                if (savedToken && currentApiUrl) {
                    // Verifichiamo il token chiamando /user
                    // Qui usiamo l'istanza 'api' importata che ora userà l'URL e il token
                    const userRes = await api.get("/user");

                    const result = userRes.data;
                    const loadedUser: UserData = {
                        name: result.nome,
                        surname: result.cognome,
                        username: result.username,
                        email: result.email,
                        role: result.role,
                        id: result.id,
                    };

                    setUser(loadedUser);
                    setIsAuthenticated(true);
                }
            } catch (error) {
                console.error('Errore durante l\'inizializzazione dell\'app:', error);
                // Se il token è scaduto o l'API fallisce, consideriamo l'utente non loggato
                await SecureStore.deleteItemAsync(KEY_TOKEN);
                setIsAuthenticated(false);
                setUser(null);
            } finally {
                setIsReady(true);
                await SplashScreen.hideAsync();
            }
        };


        // TODO: can be removed later
        // const getAuthFromStorage = async () => {
        //     try {
        //         const jsonValue = await AsyncStorage.getItem(KEY_TOKEN);
        //         if (jsonValue != null) {
        //             const auth = JSON.parse(jsonValue);
        //             setIsAuthenticated(auth.isAuthenticated);
        //         }
        //     } catch (error) {
        //         console.error('Errore nel recupero dello stato di autenticazione:', error);
        //     }
        //     setIsReady(true);
        // };
        // getAuthFromStorage();

        initApp();
    }, []);

    // TODO: Can be removed later
    // useEffect(() => {
    //     if (isReady) {
    //         SplashScreen.hideAsync();
    //     }
    // }, [isReady]);

    // 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('/(protected)/home'); // Decommenta se vuoi redirect automatico da login a home
        }
    }, [isReady, isAuthenticated, segments]);

    return (
        <AuthContext.Provider value={{ isReady, isAuthenticated, user, logIn, logOut }}>
            {children}
        </AuthContext.Provider>
    );
}