import React, { createContext, useEffect, useReducer } from 'react'
import jwtDecode from 'jwt-decode'
import axios from 'axios.js'
import { MatxLoading } from 'app/components'
import localStorageService from '../services/localStorageService'
import { apiLogin, apiGetInfor, apiLogout } from 'app/apis/Functions/users'
import { toast } from 'react-toastify'
import { SET_USER_NAVIGATION_LOGIN } from 'app/redux/actions/NavigationAction'

const initialState = {
    isAuthenticated: false,
    isInitialised: false,
    user: null,
}

const isValidToken = (accessToken) => {
    if (!accessToken) {
        return false
    }

    const decodedToken = jwtDecode(accessToken)
    const currentTime = Date.now() / 1000
    console.log(decodedToken)
    return decodedToken.exp > currentTime
}

const setSession = (accessToken) => {
    if (accessToken) {
        localStorage.setItem('accessToken', accessToken)
        axios.defaults.headers.common.Authorization = `Bearer ${accessToken}`
    } else {
        localStorage.removeItem('accessToken')
        delete axios.defaults.headers.common.Authorization
    }
}

const reducer = (state, action) => {
    switch (action.type) {
        case 'INIT': {
            const { isAuthenticated, user } = action.payload

            return {
                ...state,
                isAuthenticated,
                isInitialised: true,
                user,
            }
        }
        case 'LOGIN': {
            const { user } = action.payload
            return {
                ...state,
                isAuthenticated: true,
                user,
            }
        }
        case 'LOGOUT': {
            return {
                ...state,
                isAuthenticated: false,
                user: null,
            }
        }
        case 'REGISTER': {
            const { user } = action.payload

            return {
                ...state,
                isAuthenticated: true,
                user,
            }
        }
        default: {
            return { ...state }
        }
    }
}

const AuthContext = createContext({
    ...initialState,
    method: 'JWT',
    login: () => Promise.resolve(),
    logout: () => {},
    register: () => Promise.resolve(),
})

export const AuthProvider = ({ children }) => {
    const [state, dispatch] = useReducer(reducer, initialState)
    const login = async (username, password) => {
        const res = await apiLogin({
            username,
            password,
        })
        if (res.status === 200) {
            if (res.data.code == 200 && res.data.data) {
                localStorageService.setItem('accessToken', res.data.data.token)
                let listPath = []
                res.data.data.user_permissions.map((item) => {
                    if (item.actions) {
                        item.actions.map((e) => listPath.push(e.path))
                    }
                })
                dispatch({
                    type: 'LOGIN',
                    payload: {
                        user: { ...res.data.data, listPath },
                    },
                })
            } else {
                toast.error('Tài khoản hoặc mật khẩu không chính xác!', {
                    theme: 'colored',
                })
            }
        } else {
            toast.error('Hệ thống đang bảo trì!', {
                theme: 'colored',
            })
        }

        console.log(res.data)
    }

    const register = async (email, username, password) => {
        const response = await axios.post('/api/auth/register', {
            email,
            username,
            password,
        })

        const { accessToken, user } = response.data

        setSession(accessToken)

        dispatch({
            type: 'REGISTER',
            payload: {
                user,
            },
        })
    }

    const logout = async () => {
        setSession(null)
        const res = await apiLogout({})

        dispatch({ type: 'LOGOUT' })
    }

    useEffect(() => {
        ;(async () => {
            try {
                const accessToken = window.localStorage.getItem('accessToken')
                console.log('accessToken', accessToken)
                // if (accessToken && isValidToken(accessToken))
                if (accessToken) {
                    // setSession(accessToken)
                    const res = await apiGetInfor({})

                    console.log('res', res)

                    if (res.data.code == 200 && res.data.data) {
                        const user = res.data.data
                        console.log('res.data.data', res.data.data)
                        let listPath = []
                        user.user_permissions.map((item) => {
                            if (item.actions) {
                                item.actions.map((e) => listPath.push(e.path))
                            }
                        })
                        dispatch({
                            type: 'INIT',
                            payload: {
                                isAuthenticated: true,
                                user: { ...res.data.data, listPath },
                            },
                        })
                    } else {
                        localStorageService.setItem('accessToken', null)
                        dispatch({
                            type: 'INIT',
                            payload: {
                                isAuthenticated: false,
                                user: null,
                            },
                        })
                    }
                } else {
                    dispatch({
                        type: 'INIT',
                        payload: {
                            isAuthenticated: false,
                            user: null,
                        },
                    })
                }
            } catch (err) {
                console.error(err)
                dispatch({
                    type: 'INIT',
                    payload: {
                        isAuthenticated: false,
                        user: null,
                    },
                })
            }
        })()
    }, [])

    if (!state.isInitialised) {
        return <MatxLoading />
    }

    return (
        <AuthContext.Provider
            value={{
                ...state,
                method: 'JWT',
                login,
                logout,
                register,
            }}
        >
            {children}
        </AuthContext.Provider>
    )
}

export default AuthContext
