import { ReactNode, createContext, useEffect, useState } from 'react';
import { useContext } from 'react';
import { router, useSegments } from 'expo-router';
import AsyncStorage from '@react-native-async-storage/async-storage';

import * as SecureStore from 'expo-secure-store';
import { AuthService } from '../service/authService';

type User = {
    id: string;
    username: string;
};

type AuthProvider = {
    user: User | null;
    login: (username: string, password: string) => Promise<boolean>;
    logout: () => void;
};

function useProtectedRoute(user: User | null) {
    const segments = useSegments();

    useEffect(() => {
        const inAuthGroup = segments[0] === '(auth)';

        if (!user && inAuthGroup) {
            router.replace('/login');
        } else if (user && !inAuthGroup) {
            router.replace('/(auth)/(tabs)/(home)/mainPage');
        }
    }, [user, segments]);
}

export const AuthContext = createContext<AuthProvider>({
    user: null,
    login: async () => false,
    logout: () => {}
});

export function useAuth() {
    const context = useContext(AuthContext);
    if (!context) {
        throw new Error('useAuth must be used within a <AuthProvider />');
    }

    return context;
}

export default function AuthProvider({ children }: { children: ReactNode }) {
    const [user, setUser] = useState<User | null>(null);

    useEffect(() => {
        // Load user from AsyncStorage if token exists
        const loadUser = async () => {
            const token = await SecureStore.getItemAsync('accessToken');
            const username = await AsyncStorage.getItem('username');

            if (token) {
                // Fetch user details from backend API using the secret stored in the SecureStore
                //But back end API has not been fully developed yet.
                // For now, I am just setting a dummy user
                setUser({
                    id: '1',
                    username: username || ''
                });
            }
        };
        loadUser();
    }, [user]);

    const login = async (username: string, password: string) => {
        try {
            const loggedInUser = await AuthService.login(username, password);
            if (loggedInUser) {
                //Logic: if user successfully logs in, front end client will obtain a secret that can be used to call the backend API in order to access user's info.
                //Then those information can be set to Zustand, thereby be accessible by the front end client.
                //But back end API has not been fully developed yet.
                //So for now I set a Dummy User
                setUser({
                    id: '1',
                    username: username || ''
                });
                return true;
            } else {
                return false;
            }
        } catch (error) {
            console.error('Login error:', error);
            return false;
        }
    };

    const logout = async () => {
        try {
            await AuthService.logout();
            setUser(null);
            router.replace('/login');
        } catch (error) {
            console.log('error during logout', error);
        }
    };

    useProtectedRoute(user);

    return (
        <AuthContext.Provider value={{ user, login, logout }}>
            {children}
        </AuthContext.Provider>
    );
}
