import React, {
    createContext,
    Dispatch,
    PropsWithChildren,
    SetStateAction,
    useContext,
    useEffect,
    useState
} from "react"
import axios from "axios"

const AuthUserContext = createContext<AuthUserProps|undefined>(undefined)

interface AuthUserProps {
    authUser?: User|null,
    setAuthUser: Dispatch<SetStateAction<User | null>>,
    loadingAuthUser: boolean,
    logout: () => void,
}

export const AuthUserProvider = ({children}: PropsWithChildren) => {
    const [authUser, setAuthUser] = useState<User|null>(null)
    const [loadingAuthUser, setLoadingAuthUser] = useState(true)

    useEffect(() => {
        (async () => {
            try {
                const res = await axios.get('/api/user')
                setAuthUser(res.data)
            } catch (e) {
                // @ts-expect-error check axios response status
                if (e.response.status === 401) {
                    console.info('no user login')
                    if (window.location.pathname !== '/connexion') {
                        window.location.href = '/connexion'
                    }
                }
            } finally {
                setLoadingAuthUser(false)
            }
        })()
    }, [])

    const logout = async () => {
        try {
            setLoadingAuthUser(false)
            await axios.delete('/api/logout')
            setAuthUser(null)
            window.location.replace('/')
        } catch (e) {
            console.error(e)
        } finally {
            setLoadingAuthUser(false)
        }
    }

    return <AuthUserContext.Provider value={{authUser, setAuthUser, loadingAuthUser, logout}}>
        {children}
    </AuthUserContext.Provider>
}

const useAuthUser = () => {
    const context = useContext(AuthUserContext)
    if (context === undefined) {
        throw new Error('Add AuthUserProvider to use AuthUserContext')
    }
    return context
}

export default useAuthUser

interface User {
    id: number,
    name: string,
    email: string,
    locations: {id: number, latitude: number, longitude: number}[],
}
