// ** 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) => response,
    async (error) => {
      const originalRequest = error.config;

      if (error.response) {
        // === NEW: Handle 2FA required response ===
        if (error.response.data && error.response.data.requires2FA && !originalRequest._retry2FA) {
          originalRequest._retry2FA = true;
          // This is caught in AuthLogin.js tryLogin — do NOT reject here
          return Promise.reject(error);
        }
        // === END NEW ===

        if (error.response.status === 401 && !originalRequest._retry) {
          originalRequest._retry = true;
          const refreshToken = localStorage.getItem('refreshToken');
          if (refreshToken) {
            let isRefreshToken = localStorage.getItem('isRefreshToken');
            if (isRefreshToken) {
              return Promise.reject(error);
            }
            localStorage.setItem('isRefreshToken', 'true');
            return axios
              .post(`${apiPath}${REFRESH_TOKEN}`, { 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);
                  localStorage.setItem('axiosToken', 'Bearer ' + newAccessToken);
                  originalRequest.headers['Authorization'] = 'Bearer ' + newAccessToken;
                  localStorage.removeItem('isRefreshToken');
                  return axios(originalRequest);
                }
              })
              .catch((refreshError) => {
                dispatch(handleLogoutFunction());
                navigate('/login');
                localStorage.removeItem('isRefreshToken');
                window.location.reload();
                return Promise.reject(refreshError);
              });
          } else {
            dispatch(handleLogoutFunction());
            navigate('/login');
            window.location.reload();
          }
        }

        if (error.response.status === 500) {
          // handle 500 if needed
        }
      }

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