import React, { createContext, ReactNode, useContext, useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router";
import { Credentials, TokenData, User } from "./Types";
import { fetchUserById, logIn, tokenStatus } from "./Api";
import jwt_decode from "jwt-decode";

interface AuthContextType {
    user?: User;
    loading: boolean;
    isAirline: boolean;
    error?: any;
    login: (credentials: Credentials) => void;
    signUp: (email: string, name: string, password: string) => void;
    logout: () => void;
}

const AuthContext = createContext<AuthContextType>(
    {} as AuthContextType
);

export function AuthProvider({
    children,
}: {
    children: ReactNode;
}): JSX.Element {
    const [user, setUser] = useState<User>();
    const [error, setError] = useState<any>();
    const [loading, setLoading] = useState<boolean>(false);
    const [loadingInitial, setLoadingInitial] = useState<boolean>(true);
    const [isAirline, setIsAirline] = useState(false);
    const navigate = useNavigate();

    useEffect(() => {
        if (error) setError(undefined);
    }, [window.location.pathname]);

    useEffect(() => {
        const existingToken = localStorage.getItem("token");
        if (existingToken) {
            let airline
            try {
                airline = (jwt_decode(existingToken) as TokenData).airline;
                setIsAirline(airline)
            } catch (err) {
                setLoadingInitial(false);
                logout()
                return;
            }

            tokenStatus(existingToken)
                .then((res) => fetchUserById(res.id)
                    .then((res) => setUser(res))
                    .catch((_error) => { })
                    .finally(() => setLoadingInitial(false))
                )
                .catch((_error) => {
                    setLoadingInitial(false)
                    logout()
                })
            // .finally(() => setLoadingInitial(false));
        } else {
            setLoadingInitial(false)
        }
    }, []);

    function login(credentials: Credentials) {
        setLoading(true);
        const tokens = logIn(credentials)
            .then((x) => {
                localStorage.setItem("token", x.access_token);
                const airline = (jwt_decode(x.access_token) as TokenData).airline;
                setIsAirline(airline)
                const user = fetchUserById(x.user_id as number)
                    .then(y => {
                        setUser(y);
                        navigate("/home")
                    })
                    .catch((error) => setError(error))
                    .finally(() => setLoading(false));
            })
            .catch((error) => setError(error))
        // .finally(() => setLoading(false));
    }

    function signUp(email: string, name: string, password: string) { }

    function logout() {
        localStorage.removeItem("token");
        setUser(undefined);
        navigate("/login")
    }

    const memoedValue = useMemo(
        () => ({
            user,
            loading,
            isAirline,
            error,
            login,
            signUp,
            logout,
        }),
        [user, isAirline, loading, error]
    );

    return (
        <AuthContext.Provider value={memoedValue}>
            {!loadingInitial && children}
        </AuthContext.Provider>
    );
}

export default function useAuth() {
    return useContext(AuthContext);
}