import { get, post, saveGuestToken, saveToken, setDefaultToken } from '../../utils/api'
import * as U from '../../utils/apiUrls'
import * as T from '../../utils/types'
import { IP_COUNTRY, CURRENT_IP } from '@/store/utils/localStorageKeys'
import { IS_LOGGED_IN_GUEST_GETTER_NAME } from '@/config/defaults'
import { getValue } from '@/helpers/variable-handling'

/**
 * LoginUser
 *
 * Logs the user in and saves the tokens, then retrieves member details, and loads countries afterwards loads menus and
 * login user
 * TODO: change this for mutant subscriptions
 *
 * @param commit
 * @param dispatch
 * @param getters
 * @param data
 */
export const loginUser = async ({ commit, dispatch, getters }, data) => {
  commit(T.PROCESSING_STARTED, 'login')
  // Reset status
  await dispatch('removeError', 'login')
  commit(T.SET_RESET_ALERT, false)
  commit(T.SET_CHANGE_PASSWORD_STATUS, false)
  dispatch('setPreferredContactVerificationStatus')

  // Get login response
  let response =
    data.response ||
    (await post(U.API_LOGIN_URL, { ...data, platform: 'eshop-' + getters.getCurrentVersion }).catch(error => {
      commit(T.PROCESSING_FINISHED, 'login')
      dispatch('logError', {
        login: (error.response.status === 403 && error.response.data.error) || 'Login.LoginForm.ErrorLoginMessage',
      })
      return error
    }))

  if (getValue(response, 'data.access_token')) {
    dispatch('setAppClasses', response.data.on_behalf === true ? ['on_behalf_logged_in'] : [])
    // Set token
    await commit(T.SET_TOKEN, response.data)
    await saveToken(response.data.access_token)
    await setDefaultToken(response.data.access_token)

    // Verify member details
    let userData = await get(U.API_USER_URL).catch(error => {
      commit(T.PROCESSING_FINISHED, 'login')
      dispatch('logError', { login: error })
      return error
    })

    if (userData && userData.data && userData.data.member) {
      // clear login data cache
      commit(T.LOGOUT_USER)
      if (getters[IS_LOGGED_IN_GUEST_GETTER_NAME]) {
        dispatch('logoutGuest', false)
      }

      commit(T.SET_CHANGE_PASSWORD_STATUS, userData.data.change_password)
      dispatch('setPreferredContactVerificationStatus', {
        requires: userData.data.verify_contact,
        skipVerification: !userData.data.force_contact_verification,
      })
      await dispatch('updateUserDetails', userData.data)
      await dispatch('loadMemberDetails', userData.data.member)
      await dispatch('loadCountries')
      await dispatch('loadAllLanguages')
      await dispatch('updateUserCountryById', userData.data.member.country_id)
      await dispatch('generateMenus', userData.data.member)
      await dispatch('updateSelectedLanguage', getters.getMemberInformation.language_id)
      await dispatch('showiSPPopup')
      commit(T.LOGIN_USER)
      commit(T.PROCESSING_FINISHED, 'login')

      return response.data
    } else {
      await dispatch('logError', { login: 'Login.LoginForm.ErrorNotMember' })
      return Error('User is not an member')
    }
  }
}

export const updateUserDetails = ({ commit, dispatch }, data) => {
  commit(T.SET_LOGIN_USER, data)
}

export const updateGuestUserDetails = ({ commit, dispatch }, data) => {
  commit(T.SET_LOGIN_GUEST_USER, data)
}

export const logoutUser = ({ commit, dispatch }, data = '/') => {
  let lastKnownIp = localStorage.getItem(CURRENT_IP)
  let countryIpList = JSON.parse(localStorage.getItem(IP_COUNTRY)) || {}

  commit(T.UNSET_COUNTRY)
  dispatch('clearMenus')
  commit(T.SET_LOGIN_USER, null)
  // Logout should be the last one or the user will be logout before the menus are removed by the security plugin
  localStorage.clear()
  sessionStorage.clear()
  commit(T.LOGOUT_USER)

  if (countryIpList[lastKnownIp]) {
    localStorage.setItem(IP_COUNTRY, JSON.stringify({ [lastKnownIp]: countryIpList[lastKnownIp] }))
  }
  window.location = data
}

export const sendResetLink = ({ commit, dispatch }, payload) => {
  dispatch('removeError', 'login')
  commit(T.PROCESSING_STARTED, 'resetpassword')
  return post(U.API_EMAIL_PASSWORD_URL, payload)
    .then(response => {
      commit(T.SHOW_RESET, false)
      commit(T.SET_RESET_ALERT, true)
      commit(T.PROCESSING_FINISHED, 'resetpassword')
      commit(T.SET_RESET_ERROR_STATUS, false)
      dispatch('activateReset', false)
      commit(T.SET_RESET_STATUS, true)
      commit(T.SET_RESET_RESPONSE_DATA, response.data)
    })
    .catch(error => {
      commit(T.SET_RESET_ERROR_MESSAGE, null)
      if (typeof error.response.data !== 'undefined') {
        commit(T.SET_RESET_ERROR_MESSAGE, error.response.data)
      }
      commit(T.SET_RESET_RESPONSE_DATA, null)
      commit(T.SET_RESET_ERROR_STATUS, true)
      commit(T.PROCESSING_FINISHED, 'resetpassword')
      dispatch('logError', { resetPassword: error.response.data })
    })
}

export const sendResetPassword = ({ commit, dispatch }, data) => {
  commit(T.PROCESSING_STARTED, 'resetpassword')
  dispatch('removeError', 'resetPassword')
  commit(T.SET_PREFERRED_CONTACT, data)
  return post(U.API_RESET_PASSWORD_URL, data)
    .then(response => {
      commit(T.SET_RESET_RESPONSE_DATA, null)
      commit(T.SET_RESET_ERROR_STATUS, false)
      commit(T.SET_RESET_ERROR_MESSAGE, null)
      commit(T.PROCESSING_FINISHED, 'resetpassword')
    })
    .catch(error => {
      commit(T.SET_RESET_RESPONSE_DATA, null)
      commit(T.SET_RESET_ERROR_STATUS, true)
      commit(T.PROCESSING_FINISHED, 'resetpassword')
      dispatch('logError', { resetPassword: error.response.data })
    })
}

export const activateReset = ({ commit, dispatch, getters }, data) => {
  dispatch('removeError', 'login')
  commit(T.ACTIVATE_RESET, data)
  commit(T.SHOW_RESET, data)
  if (data === false) {
    commit(T.SET_RESET_STATUS, false)
    commit(T.SET_RESET_ERROR_STATUS, false)
    commit(T.SET_RESET_ERROR_MESSAGE, null)
    commit(T.SET_RESET_RESPONSE_DATA, null)
  } else {
    if (getters.getResetAlert === true) {
      commit(T.SET_RESET_ALERT, false)
    }
  }
}

export const setResetStatus = ({ commit }, data) => {
  commit(T.SET_RESET_STATUS, data)
}

export const setResetAlert = ({ commit }, data) => {
  commit(T.SET_RESET_ALERT, data)
}

export const setResetErrorStatus = ({ commit }, data) => {
  commit(T.SET_RESET_ERROR_STATUS, data)
}

export const setResetResponseData = ({ commit }, data) => {
  commit(T.SET_RESET_RESPONSE_DATA, data)
}

export const setResetAlertStatus = ({ commit }, data) => {
  commit(T.SET_RESET_ALERT, data)
}

export const guestLogin = async ({ commit, dispatch, getters }, payload) => {
  commit(T.PROCESSING_STARTED, 'guest_login')

  let response = {}
  if (payload.accessToken) {
    // login with token
    response['data'] = {
      token_type: 'Bearer',
      expires_in: payload.expiredIn || 2592000,
      access_token: payload.accessToken,
    }
  } else {
    payload = payload ? payload + '&' : '?'
    response = await get(U.API_GUEST_LOGIN + payload + 'platform=' + 'eshop-' + getters.getCurrentVersion).catch(
      error => {
        commit(T.PROCESSING_FINISHED, 'guest_login')
        dispatch('logError', { login: error })
        return error
      }
    )
  }

  await saveGuestToken(response.data.access_token)
  await commit(T.SET_GUEST, response.data)
  await commit(T.SET_LOGIN_GUEST_USER_LOGIN_STATUS, true)
  await commit(T.PROCESSING_FINISHED, 'guest_login')

  let userdata = await get(U.API_USER_URL).catch(error => {
    commit(T.PROCESSING_FINISHED, 'guest_login')
    dispatch('logError', { login: error })
    return error
  })
  if (userdata && userdata.data !== 'undefined') {
    await dispatch('loadCountries')
    await dispatch('updateGuestUserDetails', userdata.data)
    return userdata.data
  } else {
    commit(T.PROCESSING_FINISHED, 'login')
    dispatch('logError', { login: 'User is not a member' })
    return Error('User is not an member')
  }
}

export const logoutGuest = async ({ commit, dispatch }, resetAxiosToken = true) => {
  if (resetAxiosToken) {
    await saveGuestToken('')
  }
  commit(T.SET_LOGIN_GUEST_USER_LOGIN_STATUS, false)
  dispatch('updateGuestUserDetails', {})
}

export const disableRouteCheck = ({ commit }, payload) => {
  commit(T.DISABLE_ROUTE_CHECK, payload)
}

export const setPreferredContactVerificationStatus = ({ commit }, data = {}) => {
  commit(T.SET_CONTACT_VERIFICATION_STATUS, data)
}
