import * as T from '@/store/utils/types'
import {
  ESHOP_PRODUCT_GET_PRODUCT_CATEGORIES,
  ESHOP_PRODUCT_GET_PRODUCTS,
  ESHOP_PRODUCT_DETAILS,
  ESHOP_KITTING_DETAILS,
  ESHOP_CBP_BREAKDOWN,
  ESHOP_SEARCH_RECOMMENDATION,
} from '@/store/utils/apiUrls'
import { get, post } from '@/store/utils/api'
import _ from 'lodash'
import helpers from '@/helpers'
import querystring from 'querystring'

export const loadProductCategories = async ({ commit, dispatch, getters }, payload = { setCategory: true }) => {
  commit(T.PROCESSING_STARTED, 'categoriesLoading', { root: true })
  let cancelToken = await dispatch('generateCancelToken', 'categories', { root: true })
  return get(ESHOP_PRODUCT_GET_PRODUCT_CATEGORIES, cancelToken.token)
    .then(response => {
      let categories = response.data
      commit(T.ESHOP_PRODUCT_SET_CATEGORIES, categories)
      // set the first return as the category if its not a sub category
      let currentCategory = false
      let currentStateCategory = getters.getProductCurrentCategory
      if (helpers.getValue(currentStateCategory, 'id') === false) {
        for (let i in categories) {
          if (
            typeof categories[i].parent_id !== 'undefined' &&
            categories[i].parent_id === 1 &&
            categories[i].for_sales === 1 &&
            categories[i].name.toLowerCase() === 'health food'
          ) {
            currentCategory = categories[i]
            break
          }
        }
        if (!currentCategory) {
          for (let b in categories) {
            if (
              typeof categories[b].parent_id !== 'undefined' &&
              categories[b].parent_id === 1 &&
              categories[b].for_sales === 1
            ) {
              currentCategory = categories[b]
              break
            }
          }
        }
      } else {
        currentCategory = currentStateCategory
      }
      if (payload.setCategory) {
        commit(T.ESHOP_PRODUCT_SET_CURRENT_CATEGORY, currentCategory)
      }
    })
    .catch(e => {
      dispatch('logError', { category_loading: e }, { root: true })
    })
    .finally(() => {
      commit(T.PROCESSING_FINISHED, 'categoriesLoading', { root: true })
    })
}

export const productChangeCurrentCategory = ({ commit, getters }, categoryId) => {
  let categories = getters.getProductMainCategorires
  let currentCategory = getters.getProductCurrentCategory
  for (let i in categories) {
    if (categories[i].id === categoryId) {
      currentCategory = categories[i]
      break
    }
  }
  commit(T.ESHOP_PRODUCT_SET_CURRENT_CATEGORY, currentCategory)
}

export const setProductSortOrder = ({ commit }, sortOrderId) => {
  commit(T.ESHOP_PRODUCT_SET_SORT_ORDER, sortOrderId)
}

export const filterProductsForSaleTypes = ({ commit, getters, rootGetters, dispatch }, salesTypeIds) => {
  dispatch(
    'loadFetchMasterDataId',
    {
      master: 'SALE_TYPES',
      data: 'RE_PURCHASE',
    },
    { root: true }
  ).then(repurchaseData => {
    if (repurchaseData) {
      if (salesTypeIds.length === 0) {
        salesTypeIds = [repurchaseData]
      }
      commit(T.ESHOP_PRODUCT_SET_SALES_TYPES_FILTER_IDS, salesTypeIds)
    }
  })
}

export const filterEkSmartProducts = ({ commit }, isEkSmart) => {
  commit(T.ESHOP_PRODUCT_SET_IS_EK_SMART, isEkSmart)
}

export const filterProductPriceRange = ({ commit }, payload) => {
  commit(T.ESHOP_PRODUCT_SET_PRICE_RANGE_FILTER, payload)
}

export const filterProductCvRange = ({ commit }, payload) => {
  commit(T.ESHOP_PRODUCT_SET_CV_RANGE_FILTER, payload)
}

export const filterProductsSubCategory = ({ commit }, subCategories) => {
  commit(T.ESHOP_PRODUCT_SET_SELECTED_SUB_CATEGORY, subCategories)
}

export const filterProductsName = ({ commit }, subCategories) => {
  commit(T.ESHOP_PRODUCT_SET_SEARCH_NAME, subCategories)
}

export const initProducts = async ({ dispatch, rootGetters, getters }) => {
  let name = getters.getProductSearchName || ''
  let category = getters.getProductCurrentCategory
  let country = rootGetters.getSelectedCountry
  let location = rootGetters.getSelectedCountryLocation
  let salesTypes = getters.getFilteredSalesTypes
  let isEkSmart = getters.getIsEkSmart
  let priceRange = getters.getFilteredPriceRange || [0, 0]
  let cvRange = getters.getFilteredCvRange || [0, 0]
  let sortOrder = getters.getProductSortOrder
  let pagination = rootGetters.getPagination('products') || { limit: getters.getProductsPerPage, offset: 0 }
  let subCategories = getters.getProductSelectedSubCategories
  let categories = (subCategories.length && subCategories) || (category.id && [category.id]) || []
  rootGetters.afterLoading('categoriesLoading').then(async () => {
    dispatch('loadProducts', {
      name: name,
      countryId: country.id,
      locationId: location.id,
      salesTypesIds: salesTypes,
      ek_smart: isEkSmart,
      priceRange: priceRange,
      cvRange: cvRange,
      sortOrder: sortOrder,
      pagination: pagination,
      categoryIds: categories,
    })
  })
}

/**
 * Load Products
 * @param commit
 * @param rootGetters
 * @param dispatch
 * @param getters
 * @param payload
 * @returns {Promise<*>}
 */
export const loadProducts = async ({ commit, rootGetters, dispatch, getters }, payload) => {
  let name = payload.name
  let countryId = payload.countryId
  let locationId = payload.locationId
  let salesTypesIds = payload.salesTypesIds
  let ekSmart = payload.ek_smart
  let priceRange = payload.priceRange || []
  let cvRange = payload.cvRange || []
  let sortOrder = payload.sortOrder
  let pagination = payload.pagination || { limit: 20, offset: 0 }
  let categoryIds = payload.categoryIds
  let cancelToken = await dispatch('generateCancelToken', 'products', { root: true })
  let identifier = payload.identifier || 'products'
  let filters = payload.filters || getters.getDefaultFilters
  let isRp = payload.is_rp || false
  commit(T.PROCESSING_STARTED, identifier, { root: true })
  return await post(
    ESHOP_PRODUCT_GET_PRODUCTS,
    {
      name: name,
      country_id: countryId,
      location_id: locationId,
      categories: categoryIds,
      sales_types: salesTypesIds,
      price_min: priceRange[0],
      price_max: priceRange[1],
      cv_min: cvRange[0],
      cv_max: cvRange[1],
      sortby: sortOrder,
      is_ek_smart: ekSmart,
      is_rp: isRp,
      limit: pagination.limit,
      offset: pagination.offset || 0,
      filters: filters,
    },
    cancelToken.token
  )
    .then(async response => {
      let products = response.data.data
      if (typeof payload.readOnly === 'undefined' || payload.readOnly === false) {
        commit(payload.commit || T.ESHOP_PRODUCT_SET, products)
        commit(T.ESHOP_PRODUCT_SET_TOTAL, response.data.total)
        if (response.data.filters !== undefined) {
          // Reset / Update Price Range
          let priceMin = helpers.getNumberValue(response.data.filters.price_range.min)
          let priceMax = helpers.getNumberValue(response.data.filters.price_range.max)
          // Reset / Update CV Range
          let cvMin = helpers.getNumberValue(response.data.filters.cv_range.min)
          let cvMax = helpers.getNumberValue(response.data.filters.cv_range.max)
          if (
            (getters.getFilteredPriceRange.length === 2 &&
              getters.getFilteredPriceRange[0] === 0 &&
              getters.getFilteredPriceRange[1] === 0) ||
            (getters.getAvailableFilters.price_range.min !== 0 &&
              getters.getAvailableFilters.price_range.min < priceMin) ||
            (getters.getAvailableFilters.price_range.max !== 0 &&
              getters.getAvailableFilters.price_range.max < priceMax)
          ) {
            await dispatch('filterProductPriceRange', { value: [priceMin, priceMax], isInitial: true })
          }

          if (
            (getters.getFilteredCvRange.length === 2 &&
              getters.getFilteredCvRange[0] === 0 &&
              getters.getFilteredCvRange[1] === 0) ||
            (getters.getAvailableFilters.cv_range.min !== 0 && getters.getAvailableFilters.cv_range.min < cvMin) ||
            (getters.getAvailableFilters.cv_range.max !== 0 && getters.getAvailableFilters.cv_range.max < cvMax)
          ) {
            await dispatch('filterProductCvRange', { value: [cvMin, cvMax], isInitial: true })
          }
          commit(T.ESHOP_PRODUCT_SET_AVAILABLE_FILTERS, response.data.filters)
        }
      }
      commit(T.PROCESSING_FINISHED, identifier, { root: true })
      return products
    })
    .catch(e => {
      commit(T.PROCESSING_FINISHED, identifier, { root: true })
      dispatch('logError', { products_loading: e }, { root: true })
    })
}

export const loadProductOrKittingDetails = async ({ commit, rootGetters, dispatch }, payload) => {
  let cancelToken = await dispatch(
    'generateCancelToken',
    'products_details_' + payload.product_id + '_' + payload.kitting_id,
    { root: true }
  )
  let url = helpers.isEmpty(payload.product_id) ? ESHOP_KITTING_DETAILS : ESHOP_PRODUCT_DETAILS
  commit(T.PROCESSING_STARTED, 'productOrKittingDetails', { root: true })
  return post(
    url,
    _.merge(
      {
        country_id: payload.country_id || rootGetters['enrolment/getEnrolCountryId'],
      },
      payload
    ),
    cancelToken.token
  )
    .then(response => {
      let result = _.merge({ details: response.data }, payload)
      commit(T.ESHOP_SET_PRODUCT_OR_KITTING_DETAILS, result)
      commit(T.PROCESSING_FINISHED, 'productOrKittingDetails', { root: true })
      return result
    })
    .catch(e => {
      dispatch('logError', { category_loading: e }, { root: true })
      commit(T.PROCESSING_FINISHED, 'productOrKittingDetails', { root: true })
      return false
    })
}
export const isRetailPrice = ({ commit }, payload = false) => {
  commit(T.SET_IS_RETAIL_PRICE, payload)
}

export const loadProductCbpBreakDown = async ({ commit, dispatch }, kittingId) => {
  commit(T.PROCESSING_STARTED, 'loadingCbpBreakdown', { root: true })
  let cancelToken = await dispatch('generateCancelToken', 'cbpBreakdown', { root: true })

  return await get(ESHOP_CBP_BREAKDOWN + kittingId, cancelToken.token)
    .then(result => {
      return result.data
    })
    .catch(() => {
      return { error: true }
    })
    .finally(() => {
      commit(T.PROCESSING_FINISHED, 'loadingCbpBreakdown', { root: true })
    })
}

export const fetchProductSearchRecommendation = async ({ commit, dispatch }, payload) => {
  commit(T.PROCESSING_STARTED, 'loadProductSearchRecommendation', { root: true })
  let query = '?' + querystring.stringify(payload)
  let cancelToken = await dispatch('generateCancelToken', 'productSearchRecommendation', { root: true })

  return await get(ESHOP_SEARCH_RECOMMENDATION + query, cancelToken.token)
    .then(response => {
      return (response.data && response.data.data) || []
    })
    .finally(() => {
      commit(T.PROCESSING_FINISHED, 'loadProductSearchRecommendation', { root: true })
    })
}
