// ** UseJWT import to get config
import axios from "axios";
import {isUserLoggedIn} from "../utils/Utils";
import jwtApplicationConfig from "auth/jwtApplicationConfig";
import jwt_decode from "jwt-decode";
import {apiPath} from "./utils";

//import axios from "axios";
export const refreshIntervalName = 'refreshInterval'
export const predictProductionQty = 'predictProductionQty'
export const predictUsageCount = 'predictUsageCount'
export const windowCount = 'windowCount'
import {useNavigate} from "react-router-dom";
import {useDispatch} from "react-redux";
import { REFRESH_TOKEN } from 'utils/ApiPathConst';
import { getMessage } from 'utils/getI18nMessage';

// Guard so we only register interceptors once (ThemeRoutes re-renders add duplicate handlers otherwise)
let axiosInterceptorsSetup = false;
// In-memory guard so only one 401/logout flow shows the alert (avoids race when multiple 401s or interceptors run)
let expiredAlertShownInMemory = false;

// ** Handle User Login
export const handleLogin = data => {
    return dispatch => {

        dispatch({
            type: 'LOGIN',
            data,
            jwtApplicationConfig,
            accessToken: data['accessToken'],
            refreshToken: data['refreshToken']
        })

        // console.log(data)
        // ** Add to user, accessToken & refreshToken to localStorage
        localStorage.setItem('userData', JSON.stringify(data))
        localStorage.setItem('accessToken', data.accessToken)
        localStorage.setItem('refreshToken', data.refreshToken)
        localStorage.setItem('axiosToken', "Bearer " + data.accessToken)
        localStorage.setItem('searchCriteria',"")
        //localStorage.setItem(config.storageUserRoleKeyName, JSON.stringify(data.role).slice(1).slice(0, -1))
        localStorage.setItem(refreshIntervalName, "60")
        // for demo only
        localStorage.setItem(windowCount, '0')
        localStorage.setItem(predictProductionQty, '0')
        localStorage.setItem(predictUsageCount, '0')
        localStorage.removeItem('expiredAlertShown')
        expiredAlertShownInMemory = false
    }
}

export const isLocalTokenValid = () => {
    axios.get(`${apiPath}/test`)
        .then((response) => {
            if(response.status === 200){
                return true;
            }
            else{
                return false;
            }
        })
        .catch(error => {
            console.log(error);
            return false;
        });
    return false;
}

export const isTokenValid = () =>{
    if(localStorage.getItem('accessToken') !== null && localStorage.getItem('accessToken') !== 'null'){
        let isExpired = false;
        const token = localStorage.getItem('accessToken');
        let decodedToken=jwt_decode(token);
        let dateNow = new Date();

        if(decodedToken.exp < dateNow.getTime())
            isExpired = true;
        return isExpired;
    }
    else{
        return false;
    }
}

// ** Handle User Logout
export const handleLogoutFunction = () => {
    return dispatch => {
        dispatch({
                type: 'LOGOUT',
                accessToken: null,
                refreshToken: null
            }
        )

        // console.log("logout");
        // ** Remove user, accessToken & refreshToken from localStorage
        localStorage.removeItem('userData')
        localStorage.removeItem('accessToken')
        localStorage.removeItem('refreshToken')
        localStorage.removeItem('webtoken')
        localStorage.removeItem('transactionid')
        localStorage.removeItem('searchCriteria')
        //localStorage.removeItem(config.storageUserRoleKeyName)
        // Do not clear expiredAlertShown / expiredAlertShownInMemory here: logout runs right after
        // the token-expired alert, and parallel 401s would each show another popup if we reset.
        // Reset those only on successful login (handleLogin).
        localStorage.removeItem(refreshIntervalName)
        localStorage.removeItem(windowCount)
        localStorage.removeItem(predictProductionQty)
        localStorage.removeItem(predictUsageCount)
        // setTimeout(()=> localStorage.removeItem("expiredAlertShown"), 5000)
    }
}

// ** Handle axios token
export const SetupAxiosInterceptors = () => {
    const navigate = useNavigate()
    const dispatch = useDispatch();
    //const updateLastRequestTime = useContext(TimerContext);
    let isRefreshToken= false;

    // Avoid stacking interceptors on every ThemeRoutes re-render (would cause multiple alerts on 401)
    if (axiosInterceptorsSetup) {
        return;
    }
    axiosInterceptorsSetup = true;

    axios.interceptors.request.use(
        config => {
            // ** Get token from localStorage
            const accessToken = localStorage.getItem("accessToken")

            // ** If token is present add it to request's Authorization Header
            if (isUserLoggedIn()) {
                config.headers.Authorization = `${jwtApplicationConfig.tokenType} ${accessToken}`
            }
            config.headers['X-Authorization'] = process.env.REACT_APP_API_KEY
            return config
        },
        error => {
            Promise.reject(error)
        }
    )

    axios.interceptors.response.use(
        response => {
            //updateLastRequestTime(Date.now());
            return response;
        },
        async (error) => {
            // const { config, response: { status } } = error
            const status = error.response?.status
            const reqUrl = error.config?.url || ''
            // iAM Smart registration: HKID already linked — caller must show /iamsmart/pleaseLogin (not refresh/logout)
            if (
                status === 401 &&
                reqUrl.includes('/smart/getProfile') &&
                error.response?.data?.exception === 'msg: account created'
            ) {
                return Promise.reject(error)
            }
            if (status === 401 && error.config?.url !== apiPath + REFRESH_TOKEN) {
                // Make a request to refresh the access token
                const refreshToken = localStorage.getItem('refreshToken');
                if (isRefreshToken) {
                  return;
                }
                isRefreshToken = true;
                return axios
                    .post(`${apiPath}${REFRESH_TOKEN}`, {
                      refreshToken: refreshToken // Replace with your refresh token
                    })
                    .then((response) => {
                      if (response.status === 200) {
                        const newAccessToken = response.data.accessToken;
                        const newRefreshToken = response.data.refreshToken;
                        localStorage.setItem('accessToken', newAccessToken);
                        localStorage.setItem('refreshToken', newRefreshToken);
                        isRefreshToken = false;
                        window.location.reload();
                      }
                    })
                    .catch((refreshError) => {
                      isRefreshToken = false;
                      if (!expiredAlertShownInMemory && localStorage.getItem("expiredAlertShown") === null) {
                        expiredAlertShownInMemory = true;
                        localStorage.setItem("expiredAlertShown", "true");
                        alert(getMessage("autoLogout"));
                      }
                      dispatch(handleLogoutFunction());
                      navigate('/login');
                      window.location.reload();
                      throw refreshError;
                    });
            } else {
                if (error.response && error.response.status === 401) {
                    if (!expiredAlertShownInMemory && localStorage.getItem("expiredAlertShown") === null) {
                        expiredAlertShownInMemory = true;
                        localStorage.setItem("expiredAlertShown", "true");
                        alert(getMessage("autoLogout"));
                    }
                }
    
                // ** if (status === 401) {
                // if (response.status === 401) {
                //     if (localStorage.getItem("expiredAlertShown") === null) {
                //         localStorage.setItem("expiredAlertShown", true)
                //         alert("登入驗證已過期，請重新登入。")
                //     }
                // }
    
                // if (response && response.status === 401) {
                //     if (localStorage.getItem("expiredAlertShown") === null) {
                //         localStorage.setItem("expiredAlertShown", true)
                //         alert("登入驗證已過期，請重新登入。")
                //     }
                // }
    
                if (localStorage.getItem("expiredAlertShown")) {
                    await dispatch(handleLogoutFunction());
                    await navigate('/login');
                    await window.location.reload();
                }

                if (error.response?.status === 500){
                    //setIsUploading(false);
                }
                // console.log(error)
            }
            
            return Promise.reject(error)
        }
        
    )
}

export const handleRefreshTokenFunction = () => {
    // const token = localStorage.getItem('accessToken');
    let isRefresh = false;
    
    if (!isRefresh) {
        const refreshToken = localStorage.getItem('refreshToken');
        isRefresh = true;
        axios.post(`${apiPath}${REFRESH_TOKEN}`, {
            refreshToken: refreshToken
        }).then((response) => {
            if (response.status === 200) {
                const newAccessToken = response.data.accessToken;
                const newRefreshToken = response.data.refreshToken;
                localStorage.setItem('accessToken', newAccessToken);
                localStorage.setItem('refreshToken', newRefreshToken);
                // token = newAccessToken;
                isRefresh = false;
            } else {
                // token = null;
                isRefresh = false;
            }
        })
        .catch((refreshError) => {
            console.log('Failed to refresh token');
            if (refreshError != undefined){
                console.log(refreshError)
            }
            // token = null
            isRefresh = false;
        });
    }

    return isRefresh;
}
