"use client";
import { createContext, useCallback, useContext, useEffect, useReducer } from "react";
import useRequest from "../hooks/useRequest";
import { GET_USER_ROUTE } from "@/core/utils/routes";

const initAuth = {
    initAuthState: false,
    isAuth: false,
    user: {},
};

const authReducer = (state, action) => {
    switch (action.type) {
        case "CLEAR_USER":
            return { ...state, user: {} };
        case "CHANGE_USER":
            return { ...state, user: action.user };
        case "CHANGE_AUTH_STATE":
            return { ...state, isAuth: action.isAuth };
        case "CHANGE_INIT_AUTH":
            return { ...state, initAuthState: action.initAuthState };
        default:
            return state;
    }
};

const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
    const [state, dispatch] = useReducer(authReducer, initAuth);
    const request = useRequest();

    const clearUser = useCallback(() => {
        dispatch({ type: "CLEAR_USER" });
    }, []);

    const changeUser = useCallback((user) => {
        dispatch({ type: "CHANGE_USER", user });
    }, []);

    const changeAuthState = useCallback((isAuth) => {
        dispatch({ type: "CHANGE_AUTH_STATE", isAuth });
    }, []);

    const changeInitAuth = useCallback((initAuthState) => {
        dispatch({ type: "CHANGE_INIT_AUTH", initAuthState });
    }, []);

    const getUser = useCallback(async () => {
        try {
            const { data } = await request(GET_USER_ROUTE, "get");
            changeUser(data);
            changeAuthState(true);
            changeInitAuth(true);
        } catch (error) {
            if (error.response && error.response.status === 401) {
                clearUser();
                changeAuthState(false);
                changeInitAuth(true);
            }
        }
    }, [clearUser, changeUser, changeAuthState, changeInitAuth]);

    useEffect(() => {
        getUser();
    }, []);

    return (
        <AuthContext.Provider
            value={{
                user: state.user,
                isAuth: state.isAuth,
                initAuthState: state.initAuthState,
                getUser,
            }}
        >
            {children}
        </AuthContext.Provider>
    );
};

export const useAuth = () => useContext(AuthContext);
