// ** 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';
export const refreshIntervalName = 'refreshInterval';
export const predictProductionQty = 'predictProductionQty';
export const predictUsageCount = 'predictUsageCount';
export const windowCount = 'windowCount';
import { REFRESH_TOKEN } from '../utils/ApiPathConst';
//import {useContext} from "react";
//import UploadContext from "../components/UploadProvider";

// ** Handle User Login
export const handleLogin = (data) => {
  return (dispatch) => {
    dispatch({
      type: 'LOGIN',
      data,
      jwtApplicationConfig,
      accessToken: data['accessToken'],
      refreshToken: data['refreshToken'],
      subDivisionId: data['subDivisionId']
    });


    // ** 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('abilities', data.abilities);
    localStorage.setItem('subDivisionId', data.subDivisionId);
    localStorage.setItem('lotusNotesUser', data.lotusNotesUser);
    //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.setItem('checkPasswordExpired', false);

  };
};

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

    // ** Remove user, accessToken & refreshToken from localStorage
    localStorage.removeItem('userData');
    localStorage.removeItem('accessToken');
    localStorage.removeItem('refreshToken');
    localStorage.removeItem('abilities');
    localStorage.removeItem('lastVisitedPath');

    //localStorage.removeItem(config.storageUserRoleKeyName)
    localStorage.removeItem(refreshIntervalName);
    localStorage.removeItem(windowCount);
    localStorage.removeItem(predictProductionQty);
    localStorage.removeItem(predictUsageCount);
  };
};

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 axios token
export const SetupAxiosInterceptors = (dispatch, navigate) => {
  let isRefreshToken= false;
  //const { setIsUploading } = useContext(UploadContext);

  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 {response} = error
      // if (error.response.status === 401) {
      //     dispatch(handleLogoutFunction());
      //     navigate('/login');
      // }
      //
      // // ** if (status === 401) {
      // if (response.status === 401) {
      //     dispatch(handleLogoutFunction());
      //     navigate('/login');
      // }
      //
      // if (response && response.status === 401) {
      //     dispatch(handleLogoutFunction());
      //     navigate('/login');
      // }

      if (error.response.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) => {
              dispatch(handleLogoutFunction());
              navigate('/login');
              isRefreshToken = false;
              window.location.reload();
              throw refreshError;
            });
      } else {
        if (error.response.status === 401) {
          await dispatch(handleLogoutFunction());
          await navigate('/login');
          await window.location.reload();
        }

        if (error.response.status === 500){
          //setIsUploading(false);
        }
      }

      return Promise.reject(error);
    }
  );
};
