import { get, post } from '@/store/utils/api'
import {
  API_COUNTRIES_LIST_URL,
  LANGUAGES_URL,
  LANGUAGES_LIST_URL,
  STATES_LIST_URL,
  API_COUNTRY_RELATION,
  API_DYNAMIC_CONTENT,
  API_GET_LOCATION_ADDRESS_LIST_URL,
  LOCATIONS_TYPE_LIST,
  CHECK_IP,
  IP_WHOIS,
} from '../../utils/apiUrls'
import {
  SET_COUNTRIES_SHIPPING,
  SET_COUNTRIES_LOCATIONS,
  SET_CURRENT_COUNTRY,
  SET_CURRENT_LANGUAGE,
  SET_ALL_LANGUAGES,
  SET_LANGUAGES,
  SET_STATES_LOCATIONS,
  SET_USER_COUNTRY,
  SET_STATES_LOCATIONS_BY_COUNTRY,
  SET_STATES_LOCATIONS_BY_STATE,
  SET_DYNAMIC_CONTENT,
  PROCESSING_STARTED,
  PROCESSING_FINISHED,
  SET_SHIPPING_DATA,
  SET_STOCKIST_STATE_AND_CITIES,
  SET_LOCATION_TYPE_LIST,
  SET_LOCATION_NATIONALITY,
  SET_ALL_COUNTRIES_OPTION,
  SET_COUNTRY_RELATION_DATA,
  SET_AUTOSHIP_COUNTRY,
  UNSET_AUTOSHIP_COUNTRY,
  SET_CURRENT_IP,
  SET_IP_COUNTRY,
} from '../../utils/types'

import { SELECTED_COUNTRY } from '@/store/utils/localStorageKeys'
import helpers from '@/helpers'
import constants from '@/config/const'
import appSettings from '@/config/app-settings'
import _ from 'lodash'
import querystring from 'querystring'

// initialize shipping data
export const initializeShippingData = async ({ commit, getters, dispatch }, payload) => {
  let memberData = payload.member
  let shippingData = {
    user_id: memberData.user_id,
    sale_delivery_method: payload.sale_delivery_method || null,
    recipient_name: memberData.details.name,
    recipient_mobile_country_code_id: null,
    recipient_mobile_phone_number: null,
    recipient_addresses: null,
    recipient_selected_shipping_index: null,
    recipient_deleted_shipping_index: [],
    recipient_save_shipping_address: false,
    self_collection_country_id: payload.countryId,
    self_collection_state_id: null,
    self_collection_city_id: null,
    self_collection_location_id: null,
    member_addresses_id: 0,
    member_addresses: [],
    member_country_id: memberData.details.country_id,
  }
  let contactInfo = memberData.contact_info
  if (typeof contactInfo !== 'undefined' && contactInfo !== null) {
    if (!getters.getMasterDataByKey(constants.masterKey['PREFERRED_CONTACT'])) {
      await dispatch('loadMasterDataKeys', [constants.masterKey['PREFERRED_CONTACT']])
    }
    let isPrefferedEmail = getters.getMyAccountIsPreferredContactType(
      getters.getMasterDataIdByKeyAndTitle(constants.masterKey['PREFERRED_CONTACT'], constants.masterData['EMAIL'])
    )
    if (isPrefferedEmail) {
      shippingData.recipient_mobile_country_code_id = payload.countryId
      shippingData.recipient_mobile_phone_number = ''
    } else {
      if (typeof contactInfo.mobile_1_num !== 'undefined' && contactInfo.mobile_1_num !== null) {
        shippingData.recipient_mobile_country_code_id = contactInfo.mobile_1_country_code_id
        shippingData.recipient_mobile_phone_number = contactInfo.mobile_1_num
      } else if (typeof contactInfo.mobile_2_num !== 'undefined' && contactInfo.mobile_2_num !== null) {
        shippingData.recipient_mobile_country_code_id = contactInfo.mobile_2_country_code_id
        shippingData.recipient_mobile_phone_number = contactInfo.mobile_2_num
      }
    }
  }
  if (!helpers.isEmpty(memberData, 'address.address_data')) {
    shippingData.member_addresses_id = memberData.address.id
    // Remove other keys apart from title & fields
    shippingData.member_addresses = _.map(memberData.address.address_data, _.partial(_.pick, _, ['title', 'fields']))
  }
  commit(SET_SHIPPING_DATA, shippingData)
}

export const loadCountries = async ({ commit }, data) => {
  commit(PROCESSING_STARTED, 'loadCountries')
  let is_ek_smart = false
  if (typeof data !== 'undefined') {
    is_ek_smart = data.is_ek_smart
  }
  return await post(API_COUNTRIES_LIST_URL, {
    location_code: 'online',
    order: 'asc',
    active: 1,
    is_ek_smart: is_ek_smart,
  })
    .then(response => {
      commit(SET_COUNTRIES_LOCATIONS, response.data.data)
    })
    .finally(() => {
      commit(PROCESSING_FINISHED, 'loadCountries')
    })
}

export const loadAllCountries = ({ commit }, data) => {
  commit(PROCESSING_STARTED, 'locationsLoadAllCountries')
  return post(API_COUNTRIES_LIST_URL, { limit: 300, order: 'asc' }).then(response => {
    commit(SET_LOCATION_NATIONALITY, response.data.data)
    commit(SET_ALL_COUNTRIES_OPTION, response.data.data)
    commit(PROCESSING_FINISHED, 'locationsLoadAllCountries')
  })
}

export const loadShippingCountries = ({ commit, getters }) => {
  if (
    (Array.isArray(getters.getShippingCountries) && getters.getShippingCountries.length === 0) ||
    !Array.isArray(getters.getShippingCountries)
  ) {
    return post(API_COUNTRIES_LIST_URL, { order: 'asc' }).then(response => {
      commit(SET_COUNTRIES_SHIPPING, response.data.data)
    })
  }
}

export const updateUserCountryById = ({ commit }, data) => {
  return new Promise(resolve => {
    commit(SET_USER_COUNTRY, data)
    // Set selected country as user country if selected country is not defined
    let selectedCountryFromStorage = localStorage.getItem(SELECTED_COUNTRY)
    if (!selectedCountryFromStorage || selectedCountryFromStorage === 'null') {
      commit(SET_CURRENT_COUNTRY, data)
    }
    resolve()
  })
}

export const selectCountryById = ({ commit }, data) => {
  commit(SET_CURRENT_COUNTRY, data)
}

export const loadAllLanguages = async ({ commit }) => {
  return await get(LANGUAGES_URL).then(response => {
    commit(SET_ALL_LANGUAGES, response.data.data)
  })
}

/**
 * Get languange list or specific languange according to country_id
 * Empty country id will give all of languange list
 * @param commit
 * @param data {country_id: 1} or {}
 * @returns {*}
 */
export const loadLanguages = async ({ commit }, data) => {
  if (data.country_id) {
    commit(PROCESSING_STARTED, 'loadLanguages')

    return await post(LANGUAGES_LIST_URL, data)
      .then(response => {
        commit(SET_LANGUAGES, response.data.data)
      })
      .finally(() => {
        commit(PROCESSING_FINISHED, 'loadLanguages')
      })
  }
}

export const loadStates = ({ commit }, data) => {
  return get(STATES_LIST_URL)
    .then(response => {
      let states = response.data.data
      commit(SET_STATES_LOCATIONS, states)
    })
    .catch(e => {
      throw e
    })
}

export const getDynamicContent = async ({ commit }, query) => {
  commit(PROCESSING_STARTED, 'getDynamicContent')
  try {
    let res = await post(API_DYNAMIC_CONTENT, query)
    const json = res.data
    commit(SET_DYNAMIC_CONTENT, {
      data: json,
    })
    commit(PROCESSING_FINISHED, 'getDynamicContent')
  } catch (e) {
    commit(PROCESSING_FINISHED, 'getDynamicContent')
    throw e
  }
  // commit(PROCESSING_STARTED, 'getDynamicContent')
  // await post(API_DYNAMIC_CONTENT, query).then(response => {
  //   const json = response.data
  //   commit(SET_DYNAMIC_CONTENT, {
  //     data: json
  //   })
  //   commit(PROCESSING_FINISHED, 'getDynamicContent')
  // }).catch(() => {
  //   commit(PROCESSING_FINISHED, 'getDynamicContent')
  // })
}

/**
 * LoadsStockistLocation for a given country
 * @param commit
 * @param country_id
 */
export const loadStockistStateAndCities = ({ commit, dispatch, getters }, countryId) => {
  commit(PROCESSING_STARTED, 'locationsLoadStockistLocations')

  let query = {
    country_id: countryId,
    relations: ['state'],
  }

  if (getters.getAppStatus('evoucher') === true) {
    query.sale_id = getters.getSalesDetails.sale_id
  }

  return post(API_GET_LOCATION_ADDRESS_LIST_URL, query)
    .then(response => {
      commit(SET_STOCKIST_STATE_AND_CITIES, {
        country_id: countryId,
        data: response.data.data,
      })
      commit(PROCESSING_FINISHED, 'locationsLoadStockistLocations')
    })
    .catch(e => {
      dispatch('logError', { locationsLoadStockistLocations: e })
      commit(PROCESSING_FINISHED, 'locationsLoadStockistLocations')
    })
}

export const loadStatesByCountry = ({ state, commit }, query) => {
  commit(PROCESSING_STARTED, 'locationStateLoading')
  commit(PROCESSING_STARTED, 'locationStateLoading-' + query.country_id)
  return post(API_COUNTRY_RELATION, query)
    .then(response => {
      let json = response.data
      let newStates = []
      newStates = json.states.map(opt => ({
        text: opt.name,
        value: opt.id,
        country_id: opt.country_id,
      }))
      if (Object.keys(state.statesByCountriesData.data.options).length > 0) {
        // Merge options to avoid duplication retain list
        newStates = _.uniqBy([...newStates, ...state.statesByCountriesData.data.options], 'value')
      }
      commit(SET_STATES_LOCATIONS_BY_COUNTRY, {
        options: newStates,
      })
      commit(PROCESSING_FINISHED, 'locationStateLoading')
      commit(PROCESSING_FINISHED, 'locationStateLoading-' + query.country_id)
      return newStates
    })
    .catch(e => {
      commit(PROCESSING_FINISHED, 'locationStateLoading')
      commit(PROCESSING_FINISHED, 'locationStateLoading-' + query.country_id)
    })
}

export const loadCitiesByState = ({ state, commit }, query) => {
  commit(PROCESSING_STARTED, 'locationStateCitiesLoading')
  commit(PROCESSING_STARTED, 'locationStateCitiesLoading-' + query.state_id)
  return get(STATES_LIST_URL + '/' + query.state_id)
    .then(response => {
      let json = response.data
      let newCities = json.cities.map(opt => ({
        text: opt.name,
        value: opt.id,
        state_id: opt.state_id,
      }))
      let allCities = _.cloneDeep(newCities)
      if (Object.keys(state.citiesByStateData.data.options).length > 0) {
        // Merge options to avoid duplication retain list
        allCities = _.uniqBy([...allCities, ...state.citiesByStateData.data.options], 'value')
      }
      commit(SET_STATES_LOCATIONS_BY_STATE, {
        options: allCities,
      })
      commit(PROCESSING_FINISHED, 'locationStateCitiesLoading')
      commit(PROCESSING_FINISHED, 'locationStateCitiesLoading-' + query.state_id)
      return newCities
    })
    .catch(e => {
      commit(PROCESSING_FINISHED, 'locationStateCitiesLoading')
      commit(PROCESSING_FINISHED, 'locationStateCitiesLoading-' + query.state_id)
    })
}

// API call to retrieve location addresses
export const loadStockistLocationAddressList = ({ commit, dispatch }, payload) => {
  commit(PROCESSING_STARTED, 'loadStockistLocationAddressList')
  let query = {
    country_id: payload.country_id,
    state_id: payload.state_id,
    city_id: payload.city_id,
    location_id: payload.location_id,
    limit: payload.limit || 100,
    offset: 0,
    ...{ sale_id: payload.sale_id },
  }
  return post(API_GET_LOCATION_ADDRESS_LIST_URL, query)
    .then(response => {
      let data = []
      response.data.data.forEach(item => {
        data.push({
          id: item.id,
          name: item.display_name,
          country_id: item.country_id,
          state_id: item.state_id,
          city_id: item.city_id,
          area: item.area,
          location_id: item.location_id,
          telephone_num: item.telephone_num,
          telephone_code_id: item.telephone_code_id,
          mobile_phone_num: item.mobile_phone_num,
          mobile_phone_code_id: item.mobile_phone_code_id,
          address_data: JSON.parse(item.address_data),
        })
      })
      commit(PROCESSING_FINISHED, 'loadStockistLocationAddressList')
      return data
    })
    .catch(e => {
      dispatch('logError', { esac_location_address_list_loading: e })
      commit(PROCESSING_FINISHED, 'loadStockistLocationAddressList')
    })
}

export const updateSelectedCountry = ({ commit, dispatch }, countryId) => {
  commit(SET_CURRENT_COUNTRY, parseInt(countryId))
}

export const updateSelectedLanguage = ({ commit, dispatch, getters }, languageId) => {
  commit(SET_CURRENT_LANGUAGE, parseInt(languageId))
}

export const loadLocationTypeList = ({ state, commit, getters, dispatch }, query = {}) => {
  commit(PROCESSING_STARTED, 'locationTypeListLoading')
  return post(LOCATIONS_TYPE_LIST, query)
    .then(response => {
      commit(SET_LOCATION_TYPE_LIST, response.data.data)
      commit(PROCESSING_FINISHED, 'locationTypeListLoading')
    })
    .catch(error => {
      commit(PROCESSING_FINISHED, 'locationTypeListLoading')
      dispatch('logError', { locationTypeList: error })
    })
}

export const loadCountryRelation = ({ state, commit, dispatch }, query) => {
  commit(PROCESSING_STARTED, 'CountryRelationStateLoading')
  return dispatch('loadCached', {
    loaderName: 'CountryRelationStateLoading',
    payload: query,
  }).then(load => {
    if (load) {
      return post(API_COUNTRY_RELATION, query)
        .then(response => {
          let json = response.data
          commit(SET_COUNTRY_RELATION_DATA, {
            data: json,
          })
          commit(PROCESSING_FINISHED, 'CountryRelationStateLoading')
        })
        .catch(e => {
          commit(PROCESSING_FINISHED, 'CountryRelationStateLoading')
        })
    } else {
      commit(PROCESSING_FINISHED, 'CountryRelationStateLoading')
    }
  })
}

export const setAutoshipCountry = ({ commit }, payload) => {
  commit(SET_AUTOSHIP_COUNTRY, payload)
}

export const unsetAutoshipCountry = ({ commit }) => {
  commit(UNSET_AUTOSHIP_COUNTRY)
}

export const loadCountryRelationRecipientCrossCountry = ({ state, commit, dispatch }, query) => {
  commit(PROCESSING_STARTED, 'CountryRelationRecipientCrossCountryLoading')
  return post(API_COUNTRY_RELATION, query)
    .then(response => {
      let json = response.data
      commit(SET_COUNTRY_RELATION_DATA, {
        data: json,
      })
      commit(PROCESSING_FINISHED, 'CountryRelationRecipientCrossCountryLoading')
    })
    .catch(e => {
      commit(PROCESSING_FINISHED, 'CountryRelationRecipientCrossCountryLoading')
    })
}

export const loadGeoCountry = async ({ commit, getters }) => {
  commit(PROCESSING_STARTED, 'loadingGeoCountry')
  let ipWhoisKey = appSettings.ipWhois.enable && appSettings.ipWhois.key

  if (!ipWhoisKey) {
    commit(PROCESSING_FINISHED, 'loadingGeoCountry')
    return null
  }

  return await get(CHECK_IP)
    .then(async response => {
      let ip = helpers.getValue(response, 'data.ip')

      if (ip) {
        commit(SET_CURRENT_IP, ip)
        let query = '?' + querystring.stringify({ key: ipWhoisKey })

        return (
          getters.getCurrentIPCountry ||
          (await get(IP_WHOIS + ip + query).then(res => {
            let countryCode = helpers.getValue(res, 'data.country_code', 'MY')
            let countryNeighbours = helpers
              .getValue(res, 'data.country_neighbours', '')
              .split(',')
              .filter(lang => lang)
            let result = { ip, countryCode, countryNeighbours }

            commit(SET_IP_COUNTRY, result)
            return result
          }))
        )
      }

      return null
    })
    .catch(() => null)
    .finally(() => {
      commit(PROCESSING_FINISHED, 'loadingGeoCountry')
    })
}
