import {
  THIRD_PARTY_APP_CHECKOUT,
  THIRD_PARTY_APP_CHECKOUT_MEMBERSHIP,
  THIRD_PARTY_APP_CHECKOUT_PRODUCTS,
  THIRD_PARTY_APP_CHECKOUT_ACCOUNT_INFO,
  THIRD_PARTY_APP_CHECKOUT_PRODUCTS_SIZE_SELECTION,
  THIRD_PARTY_APP_CHECKOUT_CART_VIEW,
  THIRD_PARTY_APP_CHECKOUT_SHIPPING,
  THIRD_PARTY_APP_CHECKOUT_SUMMARY,
  THIRD_PARTY_APP_CHECKOUT_PWP_FOC,
  THIRD_PARTY_APP_CHECKOUT_COMPLETE,
} from '@/config/url-prefix'
import validatedRouteMixin from '@/app/_global/mixins/validatedRouteMixin'
import cartCountMixin from '@@/app/_global/mixins/cartCountMixin'
import { IS_LOGGED_IN_GETTER_NAME } from '@/config/defaults'
import { mapMasterDataId } from '@/app/_global/mixins'
import { mapGetters, mapActions } from 'vuex'
import _ from 'lodash'
import EscapeStringRegex from 'escape-string-regexp'

export default {
  mixins: [validatedRouteMixin, cartCountMixin],
  data() {
    let self = this
    return {
      routeIsLoading: false,
      routeLoadingCompleteWithDelay: false,
      routingOrder: [
        {
          path: THIRD_PARTY_APP_CHECKOUT + '/' + THIRD_PARTY_APP_CHECKOUT_MEMBERSHIP,
          previous: this.$t('3rdParty.Common.Goback.Text'),
          next: this.$t('Common.Continue'),
          title: this.$t('Enrolment.Type.Label'),
          addCallback: async () => {
            return self.getSkipEnrolmentPrivilege ? false : self.showStep(!self.isLoggedIn)
          },
          validate: async () => {
            return self.$route.query.redirect === 'true' || self.getMembershipInfoIsValid
          },
        },
        {
          path: THIRD_PARTY_APP_CHECKOUT + '/' + THIRD_PARTY_APP_CHECKOUT_PRODUCTS,
          previous: this.$t('3rdParty.Common.Goback.Text'),
          next: this.$t('Common.Continue'),
          title: this.$t('Eshop.Listing.Title'),
          addCallback: async () => {
            return self.getSkipEnrolmentPrivilege ? false : self.showStep(!self.isLoggedIn)
          },
          validate: async () => {
            let validation =
              self.$route.query.redirect === 'true' ||
              (await Promise.resolve(self.getCartTotal > 0 && self.getCheckout.status === true))
            if (validation) {
              return true
            } else {
              this.logCheckoutErrors()
              return false
            }
          },
        },
        {
          path: THIRD_PARTY_APP_CHECKOUT + '/' + THIRD_PARTY_APP_CHECKOUT_CART_VIEW,
          previous: this.$t('3rdParty.Common.Goback.Text'),
          next: this.$t('Common.Continue'),
          title: this.$t('Eshop.Checkout.Cart.Title'),
          addCallback: async () => {
            return self.getSkipEnrolmentPrivilege ? false : self.showStep()
          },
          validate: () => {
            let validation = self.$route.query.redirect === 'true' || self.getCartTotal > 0
            if (validation) {
              return true
            } else {
              self.logError({ cartError: this.$t('3rdParty.Common.ChooseProducts') })
              return false
            }
          },
        },
        {
          path: THIRD_PARTY_APP_CHECKOUT + '/' + THIRD_PARTY_APP_CHECKOUT_PRODUCTS_SIZE_SELECTION,
          previous: this.$t('3rdParty.Common.Goback.Text'),
          next: this.$t('Common.Continue'),
          title: this.$t('Eshop.PreCheckout.CheckoutSelectSizes.Next'),
          addCallback: async () => {
            return (
              ((await self.cartNeedSelection()) && self.isLoggedIn) ||
              ((await self.cartNeedSelection()) && self.showStep() && !self.isLoggedIn)
            )
          },
          validate: async () => {
            return self.$route.query.redirect === 'true' || (await self.checkAdditionalRequirementsStatus())
          },
        },
        {
          path: THIRD_PARTY_APP_CHECKOUT + '/' + THIRD_PARTY_APP_CHECKOUT_PWP_FOC,
          previous: this.$t('3rdParty.Common.Goback.Text'),
          next: this.$t('Common.Continue'),
          addCallback: async () => {
            if (self.getPwpFocSelectionComplete !== true) {
              await self.loadCartProductEligible()
            }
            return self.getEligiblePromotion.length > 0 && self.showStep()
          },
          validate: async () =>
            self.$route.query.redirect === 'true' ||
            self.getEligiblePromotion.length === 0 ||
            self.getPwpFocSelectionComplete === true,
          title: self.$t('Enrolment.Steps.Promotions.Label'),
        },
        {
          path: THIRD_PARTY_APP_CHECKOUT + '/' + THIRD_PARTY_APP_CHECKOUT_ACCOUNT_INFO,
          previous: this.$t('3rdParty.Common.Goback.Text'),
          next: this.$t('Common.Continue'),
          title: this.$t('3rdParty.Checkout.Stepper.AccountInfo.Title'),
          addCallback: async () => {
            return !self.isLoggedIn && self.showStep()
          },
          validate: async () => {
            if (
              self.getSkipEnrolmentPrivilege &&
              self.getSkipEnrolmentStatus &&
              Number.parseFloat(self.getCartAllTotalPrices.rp_price_tax || 0) <= 0
            ) {
              return false
            }
            return self.$route.query.redirect === 'true' || self.getEnrolmentInfo.status
          },
        },
        {
          path: THIRD_PARTY_APP_CHECKOUT + '/' + THIRD_PARTY_APP_CHECKOUT_SHIPPING,
          previous: this.$t('3rdParty.Common.Goback.Text'),
          next: this.$t('Common.Continue'),
          title: this.$t('Eshop.Order.Review.Step.Title'),
          addCallback: async () => {
            return self.isLoggedIn ? true : !self.isOrderComplete && self.showStep()
          },
          validate: async () => {
            await self.loadCart()
            let validation =
              self.$route.query.redirect === 'true' ||
              (self.getCartTotal > 0 &&
                !_.isEmpty(self.$helpers.getValue(self.getShippingAndPaymentInfo, 'shippingInfo')) &&
                self.getCheckout.status === true)

            if (validation || self.isOrderComplete) {
              return true
            } else {
              this.logCheckoutErrors()
              return false
            }
          },
        },
        {
          path: THIRD_PARTY_APP_CHECKOUT + '/' + THIRD_PARTY_APP_CHECKOUT_SUMMARY,
          previous: this.$t('3rdParty.Common.TryPayAgain'),
          next: this.$t('Common.Continue'),
          title: this.$t('Common.Sales.PreCheckout'),
          addCallback: async () => {
            return self.showStep()
          },
          validate: async () => self.$route.query.redirect === 'true' || self.getCartTotal > 0 || self.isOrderComplete,
        },
        {
          path: THIRD_PARTY_APP_CHECKOUT + '/' + THIRD_PARTY_APP_CHECKOUT_COMPLETE,
          get hidePrevious() {
            return (
              self.getCurrentPaymentStatus === null ||
              self.isOrderCompleteWithPayment ||
              self.getCurrentPaymentStatus === 2
            )
          },
          title: this.$t('Common.Complete'),
          get complete() {
            return self.isOrderComplete && self.isOrderCompleteWithPayment
              ? !self.isLoggedIn &&
                !self.getIsAutoshipCreationSuccess &&
                self.isAutoShip &&
                !self.getSkipEnrolmentPrivilege
                ? self.$t('3rdParty.Common.CreateAutoshipOrder.Text')
                : self.$t('Eshop.Order.GlobalWords.ContinueShopping')
              : ''
          },
          validate: async () => {
            return self.isLoggedIn ? true : await self.checkAdditionalRequirementsStatus()
          },
        },
      ],
      initialized: true,
    }
  },
  mounted() {
    let selectedCountry = JSON.parse(localStorage.getItem('COUNTRY_ID'))
    let appForm = JSON.parse(sessionStorage.getItem('APP_MEMBERSHIP_FORM'))
    if (selectedCountry && appForm && appForm.country_id && selectedCountry !== appForm.country_id) {
      this.clearLoadedData('membership')
    }
  },
  computed: {
    ...mapGetters('3rdPartyCheckoutShippingAndPayment', ['getShippingAndPaymentInfo']),
    ...mapGetters('3rdPartyCheckoutMembership', ['getMembershipInfoIsValid']),
    ...mapGetters('3rdPartyCheckoutEnrolment', [
      'getEnrolmentInfo',
      'getSkipEnrolmentPrivilege',
      'getSkipEnrolmentStatus',
    ]),
    ...mapGetters('3rdPartyCheckoutAutoship', ['isAutoShip']),
    ...mapGetters('eshop', [
      'getCartTotal',
      'getCheckout',
      'getPwpFocSelectionComplete',
      'getCartNeedAddressSelection',
      'getCartNeedSizeSelection',
      'getEligiblePromotion',
      'getCartAllTotalPrices',
    ]),
    ...mapGetters([
      'getEnrolmentRegion',
      'getErrorsState',
      'afterLoading',
      'getSelectedCountry',
      'getCurrentSaleId',
      'isLoading',
      'isOrderFailed',
      'isOrderComplete',
      'isOrderCompleteWithPayment',
      'getCurrentPaymentStatus',
      'getIsAutoshipCreationSuccess',
    ]),
    ...mapGetters({
      isLoggedIn: [IS_LOGGED_IN_GETTER_NAME],
    }),
    ...mapMasterDataId({}),
  },
  watch: {
    '$route.path': {
      async handler() {
        this.routeIsLoading = true
        await this.initPreCheckoutRoute()
        this.routeIsLoading = false
      },
      immediate: true,
    },
    routeIsLoading: {
      async handler(to) {
        if (!to) {
          // 1sec delay for route changes & remove glitches between pages
          // Todo need better solution to handle this case
          await new Promise(resolve => setTimeout(resolve, 1000))
          this.routeLoadingCompleteWithDelay = true
        }
      },
    },
    async isOrderCompleteWithPayment() {
      await this.initRouting(false)
    },
    async getIsAutoshipCreationSuccess() {
      await this.initRouting(false)
    },
    async getCurrentPaymentStatus(to) {
      if (to !== 1) {
        await this.initRouting(false)
      }
    },
  },
  methods: {
    ...mapActions(['logError', 'loadMasterDataKeysEnrolment', 'clearShoppingData']),
    ...mapActions('3rdPartyCheckoutGlobal', ['clearLoadedData']),
    ...mapActions('eshop', [
      'cartNeedSelection',
      'loadCart',
      'checkCartDummyAllSizesSelected',
      'pwpFocSelectionComplete',
      'isInstallationDetailsValid',
      'loadCartSizesDetails',
      'loadCartProductEligible',
    ]),
    async initPreCheckoutRoute() {
      await this.loadCart()
      await this.loadCartSizesDetails()
      await this.loadMasterDataKeysEnrolment({
        keys: ['sale_types', 'product_additional_requirements'],
      })
      if (this.isOrderComplete) {
        // Clearing all data
        if (this.$route.query.redirect !== 'true') {
          this.clearShoppingData(['sales'])
        }
        let completePagePath = THIRD_PARTY_APP_CHECKOUT + '/' + THIRD_PARTY_APP_CHECKOUT_COMPLETE
        // move to next page from checkout page
        await this.initRouting(false)
        this.validateRoutes = false
        // bypass validation
        if (this.isOrderCompleteWithPayment) {
          try {
            let currentRoute = this.$route
            let matchPath = _.find(this.selectedOrder, orderedRoute => {
              let regEx = new RegExp(EscapeStringRegex(orderedRoute.match || orderedRoute.path))
              return regEx.test(completePagePath)
            })
            let isCompletePath = this.$helpers.CurrentRouteHasPath(completePagePath)
            let pageParam = isCompletePath ? currentRoute.params.page || '' : ''
            this.$router.replace({ path: matchPath.path + '/' + pageParam })
          } catch (e) {
            // eslint-disable-next-line no-console
            console.error(e)
          }
        }
      } else {
        this.validateRoutes = true
        await this.initRouting(true)
      }
    },
    async checkAdditionalRequirementsStatus() {
      if (this.getCartNeedAddressSelection === true) {
        //Checks if the product installation details is valid
        if ((await this.isInstallationDetailsValid()) === false) {
          this.logError({ cartError: this.$t('Eshop.InstSelection.Invalid') })
          return false
        } else {
          return true
        }
      } else if (this.getCartNeedSizeSelection === true) {
        //Check if the dummy product have size selection
        if ((await this.checkCartDummyAllSizesSelected()) === false) {
          this.logError({ cartError: this.$t('Eshop.SizeSelection.PleaseSelect') })
          return false
        } else {
          return true
        }
      } else {
        return true
      }
    },
    logCheckoutErrors() {
      this.getCheckout.status === false
        ? this.logError({ cartError: this.$t('3rdparty.Checkout.Fail') })
        : this.logError({ cartError: this.$t('3rdParty.Common.ChooseProducts') })
    },
    showStep(customCondition = true) {
      return customCondition && (this.isOrderFailed || !this.isAutoShip || !this.isOrderComplete)
    },
  },
}
