<script>
import { mapActions, mapGetters } from 'vuex'
import _ from 'lodash'
import ConnectingLoader from '@/elements/lottie/credit_card'
import lottie from 'lottie-web'
import { popupMixin, qrLinkCopyMixin } from '@/app/_global/mixins'
import { SALES_PAYMENT_CROSS_DOMAIN_REDIRECT } from '@/store/utils/apiUrls'
import querystring from 'querystring'
import Vue from 'vue'

export default Vue.extend({
  name: 'PaymentMethods',
  mixins: [popupMixin, qrLinkCopyMixin],
  inject: {
    /**
     * Load Payment Modes Action
     *
     * @param {object} payload
     * @param {string[]} payload.exclude_payment_mode
     * @return {Promise}
     * [
     *  {
     *    value: int id,
     *    text: string name
     *  }
     *  ...
     * ]
     */
    _payment_methods_load_sales_payment_modes: {
      default: function() {
        return function(payload) {
          return this.loadSalesPaymentModes(payload)
        }
      },
    },
    /**
     * Get payment modes
     *
     * should return a function that returns the getter
     *
     * @return {function} paymentMode
     */
    _payment_methods_get_payment_modes: {
      default: function() {
        return function() {
          return this.getSalesPaymentModes
        }
      },
    },
    $validator: {},
  },
  props: {
    saleId: {
      type: Number,
    },
    excludePaymentMode: {
      type: Array,
      default: () => [],
    },
    fixedAmount: {
      type: Boolean,
      default: false,
    },
    balance: {
      type: Number,
      default: 0,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    allowZeroBalance: {
      type: Boolean,
      default: false,
    },
    checkEppPayments: {
      type: Boolean,
      default: true,
    },
    callback: {
      type: Function,
    },
    beforePaymentCallback: {
      type: Function,
      default: () => {
        return mode => Promise.resolve(mode)
      },
    },
    paymentSuccessCallback: {
      type: Function,
      default: () => {
        return mode => Promise.resolve(mode)
      },
    },
    makePaymentData: {
      type: Object,
      default: () => ({
        payType: 'sales',
        consignmentDepositId: null,
      }),
    },
    fieldTypes: {
      type: Map,
      default: () =>
        new Map([
          ['field', 'input'],
          ['dropdown', 'select'],
          ['link', 'a'],
        ]),
    },
    fieldLabels: {
      type: Map,
      default: () => new Map([['link', ' ']]),
    },
    autoFillMap: {
      type: Map,
      default: () =>
        new Map([
          ['details.member_id', vm => vm.$store.getters['getIboIdPlan']],
          ['old_member_id', vm => vm.$store.getters['getIboIdPlan']],
        ]),
    },
    showLoadingPopup: {
      type: Boolean,
      default: false,
    },
    showOnHoldPaymentOptions: {
      type: Boolean,
      default: true,
    },
    onHoldPaymentCallback: {
      type: Function,
      default: () => {
        return mode => Promise.resolve(mode)
      },
    },
    onHoldPaymentOptionsKey: {
      type: Array,
      required: true,
    },
  },
  data() {
    return {
      paymentModes: [],
      onHoldPaymentOptions: [],
      showLoading: false,
      hasPaymentError: false,
      errorMessage: null,
      errorSmall: false,
      fieldModels: {},
      inheritOptions: {},
      inheritData: {},
      qrElements: {
        embed: '',
        link: '',
      },
      paymentPopUpHtml: '',
    }
  },
  beforeCreate() {
    lottie.destroy()
  },
  render(el) {
    let self = this
    return self.rWrapper1(el, [
      el('div', [
        ...self.onHoldPaymentOptions.map((options, optionsIndex) => {
          return self.rOnHoldPaymentMethods(el, options, optionsIndex)
        }),
        // level 1 wrapper
        // If allow zero balance and balance is 0 then we dont render the payment methods, we will just show a continue button
        ...(self.allowZeroBalance && self.balance === 0
          ? [
              el('div', { class: ['active', 'pb-2'] }, [
                self.rSubmit(
                  el,
                  {
                    payment_mode_name: 'no-payment',
                    full_width: true,
                    payment_mode_code: 'no-payment',
                    no_payment: true,
                    disabled: self.disabled,
                  },
                  0
                ),
              ]),
            ]
          : self.processPaymentModes.map(function(level1, level1Index) {
              return self.rLevel1(
                el,
                level1,
                level1Index, // level1
                [
                  self.rWrapper2(
                    el, // level2 wrapper
                    level1Index,
                    level1.payment_mode_provider.map(function(paymentModeProvider, paymentModeProviderIndex) {
                      return self.rPaymentModeProvider(el, paymentModeProvider, paymentModeProviderIndex, [
                        ...paymentModeProvider.fields.map(function(field, fieldIndex) {
                          return [
                            self.rField(el, field, fieldIndex, paymentModeProvider, level1Index),
                            self.rErrorField(el, field, fieldIndex, paymentModeProvider, level1Index),
                          ]
                        }),
                        self.rSubmit(el, paymentModeProvider, level1Index),
                      ])
                    })
                  ),
                ]
              )
            })),
      ]),

      el(
        'div',
        {
          ref: 'makingPaymentLoading',
          class: ['loading-model', 'animated', 'fadeIn', { 'd-none': !this.showLoading }],
          on: { click: this.hideLoading },
        },
        [
          el(
            'div',
            {
              class: [
                this.lottieLoaderClass && !this.hasPaymentError ? this.lottieLoaderClass : 'modal-content',
                'animateRounded',
                'animateWidth',
                'no-overflow',
                { 'rounded-2': this.hasPaymentError, 'w-50': this.hasPaymentError },
              ],
            },
            [
              el('div', {
                ref: 'makingPaymentLoader',
                class: { 'd-none': this.hasPaymentError },
              }),
              el(
                'button',
                {
                  class: ['pos-absolute-tr', 'p-2', 'font-size-2', 'close', { 'd-none': !this.hasPaymentError }],
                  domProps: { type: 'button' },
                  attrs: { 'aria-label': 'Close' },
                },
                'x'
              ),
              el(
                'div',
                {
                  class: [
                    'animated',
                    'fadeIn',
                    'text-center',
                    'p-3',
                    'w-100',
                    'flex-column',
                    'justify-content-center',
                    'font-size-4',
                    { 'd-none': !this.hasPaymentError, 'd-flex': this.hasPaymentError },
                  ],
                },
                [
                  el(
                    this.errorSmall ? 'h6' : 'h4',
                    { class: ['text-center', 'no-wrap'] },
                    this.errorMessage || this.$t('Eshop.Order.Payment.Failed')
                  ),
                ]
              ),
            ]
          ),
        ]
      ),
      el(
        'b-modal',
        {
          props: {
            size: 'lg',
            'hide-header': true,
            'hide-footer': true,
            'no-close-on-backdrop': true,
            'no-close-on-esc': true,
            centered: true,
          },
          ref: 'popUpPayment',
          class: ['eshop-model'],
        },
        [
          el('div', {
            domProps: {
              innerHTML: this.paymentPopUpHtml,
            },
            on: {
              click: event => {
                if (event.target.name === 'cancel') {
                  this.$refs.popUpPayment.hide()
                } else {
                  // because popup is being blocked
                  setTimeout(this.paymentSuccessCallback, 1000)
                }
                document.getElementById('sales_payment_form').remove()
              },
            },
          }),
        ]
      ),
      el(
        'b-modal',
        {
          props: {
            size: 'lg',
            'hide-footer': true,
            'no-close-on-backdrop': true,
            'no-close-on-esc': true,
            'no-enforce-focus': true,
            centered: true,
            title: this.$t('OrderHistory.Detail.PaymentQrCode.Title'),
          },
          ref: 'popUpQrCode',
          class: ['eshop-model'],
          on: {
            hidden: this.onQrCodeHidden,
          },
        },
        [
          el(
            'div',
            {
              class: ['text-center'],
            },
            [
              // QR Code Image
              el('embed', {
                attrs: {
                  src: this.qrElements.embed,
                },
                class: ['responsive-qr'],
              }),
            ]
          ),
          el(
            'div',
            {
              class: ['text-center'],
            },
            [
              el(
                'button',
                {
                  attrs: {
                    type: 'submit',
                  },
                  class: ['btn', 'btn-primary', 'lifted'],
                  on: {
                    click() {
                      self.copyLink(self.qrElements.link, self.defaultCopiedCallBack)
                    },
                  },
                },
                this.$t('ShareQR.ShareVia.CopyLink')
              ),
            ]
          ),
        ]
      ),
    ])
  },
  mounted() {
    if (this.showOnHoldPaymentOptions) {
      this.loadOnHoldPaymentOptions(this.onHoldPaymentOptionsKey).then(data => {
        this.onHoldPaymentOptions = data || []
      })
    }
    this._payment_methods_load_sales_payment_modes({
      exclude_payment_mode: this.excludePaymentMode,
      medium: this.getMedium,
      order_total_amount: parseFloat(this.balance).toFixed(2),
    })
  },
  methods: {
    ...mapActions([
      'loadSalesPaymentModes',
      'doSalesPaymentMakePayment',
      'doSalesPaymentCrossDomainMakePayment',
      'checkPaymentModePreOrder',
      'loadOnHoldPaymentOptions',
      'setOnHoldPaymentMode',
    ]),
    rWrapper1(el, items) {
      return el('div', { attrs: { id: 'el_level_1_wrapper' } }, items)
    },
    rLevel1(el, level, level1index, items) {
      return el('div', { attrs: { id: `level1${level1index}` } }, [
        el('span', { class: { active: true } }, level.title),
        ...items,
      ])
    },
    rWrapper2(el, levelIndex, items) {
      return el('div', { attrs: { id: `el_${levelIndex}_level_2_wrapper` } }, items)
    },
    rPaymentModeProvider(el, paymentModeProvider, paymentModeProviderIndex, items) {
      return el('div', { attrs: { id: `${paymentModeProviderIndex}_level_2` } }, [
        el('span', { class: { fit: true, active: true } }, paymentModeProvider.payment_mode_name),
        ...items,
      ])
    },
    rField(el, field, fieldIndex, provider, modeIndex) {
      let self = this
      let fieldOptions = {
        props: {
          readonly:
            (this.fixedAmount && field.name === 'amount') ||
            typeof field.autofill !== 'undefined' ||
            this.disabled === true,
          placeholder: field.text,
          name: field.name,
          disabled: field.data !== undefined && this.disabled === true,
          options:
            (field.inherit !== undefined && (this.inheritData[field.inherit] || [])) || // load inherited data
            (field.data !== undefined && this.keyValueObjectToOptionsGenerator(field.data)) || // load options data
            [],
          value: this.fieldModelValue(modeIndex, field),
        },
        directives: [
          {
            name: 'validate',
            value: this.fieldValidations(field),
          },
        ],
        class: { input: true, 'border-danger': this.errors.has(field.name, provider.payment_mode_code) },
        attrs: {
          'data-vv-scope': provider.payment_mode_code,
          'data-vv-as': field.text,
          'data-qa': `${this.$helpers.kebabCase(field.text)}-${field.type}`,
          name: field.name,
        },
        on: {
          input: function(value) {
            self.updateModel(value, field, modeIndex)
          },
        },
      }
      return el(this.fieldTypes.get(field.type), fieldOptions)
    },
    rErrorField(el, field, fieldIndex, provider, modeIndex) {
      return el('span', {
        class: ['help', 'text-danger', 'small'],
        directives: [
          {
            name: 'show',
            value: this.errors.has(field.name, provider.payment_mode_code),
          },
        ],
        domProps: {
          innerHTML: this.errors.first(field.name, provider.payment_mode_code),
        },
      })
    },
    rSubmit(el, provider, lavel1Index) {
      let self = this
      return el(
        'button',
        {
          class: 'full-width',
          on: {
            click: function() {
              self.makePayment(provider, lavel1Index)
            },
          },
        },
        this.$t('Submit')
      )
    },
    fieldModelValue(providerIndex, field) {
      let self = this
      if (typeof self.fieldModels[providerIndex] === 'undefined') {
        self.fieldModels[providerIndex] = {}
      }
      // set default value
      if (self.fieldModels[providerIndex][field.name] === undefined) {
        self.fieldModels[providerIndex][field.name] =
          (field.data !== undefined &&
            (options => (options[0] !== undefined && options[0].value) || '')(
              self.keyValueObjectToOptionsGenerator(field.data)
            )) || // drop down select 1st value
          (field.inherit !== undefined &&
            (options => (options.length > 0 ? options[0].value : ''))(this.inheritData[field.inherit] || [])) || // inherited data select 1st value from inherit
          (typeof field.autofill !== 'undefined' &&
            self.autoFillMap.get(field.autofill) &&
            self.autoFillMap.get(field.autofill)(self)) || // auto-fill data from auto-fillable
          (field.name === 'amount' && self.balance !== 0 && parseFloat(self.balance).toFixed(2)) || // set amount if amount field is provided
          (field.value && field.value) || // field value if field value is provided
          ''
      } else if (field.name === 'amount' && self.fieldModels[providerIndex][field.name] === '') {
        // wait for balance field to be set
        self.fieldModels[providerIndex][field.name] = (self.balance !== 0 && parseFloat(self.balance).toFixed(2)) || ''
      }
      // initialize inherited data
      if (field.inherit !== undefined && self.inheritData[field.inherit] === undefined) {
        self.$set(self.inheritData, field.inherit, [])
      }
      // load default inherited data
      if (field.inherit_data !== undefined && self.inheritData[field.name] === undefined) {
        self.processInherited(field, self.fieldModels[providerIndex][field.name])
      }
      return self.fieldModels[providerIndex][field.name]
    },
    updateModel(value, field, levelIndex) {
      this.fieldModels[levelIndex][field.name] = value
      this.processInherited(field, value)
    },
    processInherited(field, value) {
      if (field.inherit_data !== undefined) {
        let inheritedOptions = field.inherit_data[value]
        if (inheritedOptions) {
          this.$set(this.inheritData, field.name, this.keyValueObjectToOptionsGenerator(inheritedOptions.data))
        }
      }
    },
    fieldRequired(level, field) {
      return field.name === 'amount'
    },
    fieldValidations(field) {
      return (
        (field.name === 'amount' && { required: true, decimal: 2, max_value: this.balance }) ||
        (field.required === true && { required: true }) ||
        {}
      )
    },
    makePayment(mode, index) {
      let self = this
      self.showLoading = true
      self.hasPaymentError = false
      self.errorMessage = null
      self.errorSmall = false
      self.paymentPopUpHtml = ''
      self.setOnHoldPaymentMode({ is_paylater: false, is_cash_on_delivery: false })
      mode = self.getModelData(mode, self.fieldModels[index])
      self.$validator.validateAll(mode.payment_mode_code).then(isValid => {
        if (isValid) {
          self.beforePaymentCallback(mode).then(processedMode => {
            if (mode.no_payment === true) {
              self.paymentSuccessCallback()
            } else {
              if (processedMode) {
                self
                  .doSalesPaymentMakePayment({ ...mode, ...this.getPaymentCallbackMeta })
                  .then(res => {
                    let response = res.data
                    let inlinePayment = self.enableInlinePaymentMode
                    self.checkPaymentModePreOrder(mode)
                    if (
                      typeof response.next_step !== 'undefined' &&
                      response.next_step &&
                      typeof response.form_data !== 'undefined'
                    ) {
                      var form = document.createElement('form')
                      form.target = (inlinePayment && '_self') || 'paymentForm'

                      let formData = JSON.parse(response.form_data)
                      form.setAttribute('method', formData.form_attributes.method) // form method
                      form.setAttribute('action', formData.form_attributes.action) // form action url
                      form.setAttribute('name', 'sales_payment_form') // form name
                      form.setAttribute('id', 'sales_payment_form') // form ID

                      // To create input control with javascript
                      let inputs = formData.form_inputs
                      Object.keys(inputs).forEach(function(key, value) {
                        var inputCtrl = document.createElement('input')
                        inputCtrl.type = 'hidden' // input control type
                        inputCtrl.name = key // input control name
                        inputCtrl.value = inputs[key] // input control value
                        form.appendChild(inputCtrl)
                      })

                      // To bind created form with current document body
                      document.body.appendChild(form)
                      if (inlinePayment) {
                        form.submit()
                      } else if (self.openPopupWindow(window.open('', 'paymentForm', 'fullscreen=yes,toolbar=0'))) {
                        self.errorMessage = null
                        self.hasPaymentError = false
                        form.submit()
                      } else {
                        self.showLoading = false
                        form.className = 'text-center'
                        // Form title
                        form.appendChild(
                          (function(el) {
                            el.innerText = self.$t('Common.MakePayment')
                            el.className = 'd-flex flex-column h-100'
                            return el
                          })(document.createElement('h4'))
                        )
                        // Form Message
                        form.appendChild(
                          (function(el) {
                            el.innerText = self.$t('Eshop.PaymentPopUpBlocked')
                            el.className = 'flex-grow-1 py-4'
                            return el
                          })(document.createElement('p'))
                        )
                        // Form submit
                        form.appendChild(
                          (function(el) {
                            // cancel button
                            el.appendChild(
                              (function(cancel) {
                                cancel.innerHTML = self.$t('Form.Cancel')
                                cancel.type = 'button'
                                cancel.name = 'cancel'
                                cancel.className = 'btn mr-2 btn-gray text-medium border lifted'
                                return cancel
                              })(document.createElement('button'))
                            )
                            // submit button
                            el.appendChild(
                              (function(submit) {
                                submit.innerHTML = self.$t('Eshop.Order.GlobalWords.Confirm')
                                submit.type = 'submit'
                                submit.className = 'btn btn-primary lifted'
                                return submit
                              })(document.createElement('button'))
                            )
                            return el
                          })(document.createElement('div'))
                        )
                        self.paymentPopUpHtml = form.outerHTML
                        self.$refs.popUpPayment.show()
                        self.hasPaymentError = true
                      }
                    }
                    /** Scenario
                     * 1) inline payment(TRUE), pay with cash/QR(next_step=false), and no payment error                    => call callback function
                     * 2) inline payment(TRUE), not cash payment, and no payment error                                  => NOT calling callback function
                     * 3) inline payment(FALSE), pay with cash/QR(next_step=false), and no payment error                   => call callback function
                     * 4) inline payment(FALSE), not cash payment, and no payment error                                 => call callback function
                     **/
                    if (!(inlinePayment && response.next_step === true) && !self.hasPaymentError) {
                      self.paymentSuccessCallback()
                    }
                  })
                  .catch(e => {
                    self.hasPaymentError = true
                    if (
                      e.response !== undefined &&
                      e.response.data !== undefined &&
                      Object.keys(e.response.data).find(key => Object.keys(mode).includes(key))
                    ) {
                      let value = Object.values(e.response.data)[0]
                      if (typeof value !== 'undefined' && value[0] !== undefined) {
                        self.errorSmall = true
                        self.errorMessage = value[0]
                      }
                    }
                  })
              } else {
                self.hasPaymentError = true
              }
            }
          })
        } else {
          self.showLoading = false
        }
      })
    },
    makeCrossDomainPayment(mode, index) {
      let self = this
      let inlinePayment = self.enableInlinePaymentMode
      self.showLoading = true
      self.hasPaymentError = false
      self.errorMessage = null
      self.errorSmall = false
      self.setOnHoldPaymentMode({ is_paylater: false, is_cash_on_delivery: false })
      mode = self.getModelData(mode, self.fieldModels[index])
      self.$validator.validateAll(mode.payment_mode_code).then(isValid => {
        if (isValid) {
          self.beforePaymentCallback(mode).then(processedMode => {
            if (processedMode) {
              self
                .doSalesPaymentCrossDomainMakePayment({ ...mode, ...this.getPaymentCallbackMeta })
                .then(response => {
                  let { id, reference_code } = response.data.payment
                  let query = {
                    payment_id: id,
                    reference_code: reference_code,
                  }
                  query = '?' + querystring.stringify(query)
                  if (
                    self.openPopupWindow(
                      window.open(
                        SALES_PAYMENT_CROSS_DOMAIN_REDIRECT + query,
                        (inlinePayment && '_self') || 'paymentFormCrossDomain',
                        inlinePayment ? '' : 'fullscreen=yes,toolbar=0'
                      )
                    )
                  ) {
                    self.errorMessage = null
                    self.hasPaymentError = false
                  }
                  if (!self.hasPaymentError) {
                    self.paymentSuccessCallback()
                  }
                })
                .catch(e => {
                  self.hasPaymentError = true
                  if (
                    e.response !== undefined &&
                    e.response.data !== undefined &&
                    Object.keys(e.response.data).find(key => Object.keys(mode).includes(key))
                  ) {
                    let value = Object.values(e.response.data)[0]
                    if (typeof value !== 'undefined' && value[0] !== undefined) {
                      self.errorSmall = true
                      self.errorMessage = value[0]
                    }
                  }
                })
            } else {
              self.hasPaymentError = true
              try {
                let salesErrors = self.getErrors('doSalesCartCreateSale')
                if (typeof salesErrors['selected.promotions'] !== 'undefined') {
                  self.errorSmall = true
                  self.errorMessage = salesErrors['selected.promotions']
                }
              } catch (e) {
                // eslint-disable-next-line no-console
                console.error(e)
              }
            }
          })
        } else {
          self.showLoading = false
        }
      })
    },
    getQrCode(mode, index) {
      let self = this
      self.showLoading = true
      self.hasPaymentError = false
      self.errorMessage = null
      self.errorSmall = false
      self.setOnHoldPaymentMode({ is_paylater: false, is_cash_on_delivery: false })
      mode = self.getModelData(mode, self.fieldModels[index])
      mode.is_qr = true
      self.$validator.validateAll(mode.payment_mode_code).then(isValid => {
        if (isValid) {
          self.beforePaymentCallback(mode).then(processedMode => {
            if (processedMode) {
              self
                .doSalesPaymentMakePayment({ ...mode, ...this.getPaymentCallbackMeta })
                .then(res => {
                  let response = res.data

                  self.qrElements.embed = response.image
                  self.qrElements.link = response.link

                  self.$refs.popUpQrCode.show()
                })
                .catch(e => {
                  self.hasPaymentError = true
                  if (
                    e.response !== undefined &&
                    e.response.data !== undefined &&
                    Object.keys(e.response.data).find(key => Object.keys(mode).includes(key))
                  ) {
                    let value = Object.values(e.response.data)[0]
                    if (typeof value !== 'undefined' && value[0] !== undefined) {
                      self.errorSmall = true
                      self.errorMessage = value[0]
                    }
                  }
                })
            } else {
              self.hasPaymentError = true
              try {
                let salesErrors = self.getErrors('doSalesCartCreateSale')
                if (typeof salesErrors['selected.promotions'] !== 'undefined') {
                  self.errorSmall = true
                  self.errorMessage = salesErrors['selected.promotions']
                }
              } catch (e) {
                // eslint-disable-next-line no-console
                console.error(e)
              }
            }
          })
        } else {
          self.showLoading = false
        }
      })
    },
    onQrCodeHidden() {
      this.paymentSuccessCallback()
    },
    keyValueObjectToOptionsGenerator(data) {
      let options = []
      if (typeof data !== 'undefined') {
        Object.keys(data).forEach(function(key) {
          let obj = {
            value: key,
            text: data[key],
          }
          options.push(obj)
        })
      }
      return options
    },
    getModelData(mode, data) {
      return _(mode)
        .omitBy(_.isUndefined)
        .omitBy(_.isNull)
        .thru(mode => {
          mode.fields = _.map(mode.fields, function(field) {
            field.value = data[field.name]
            return field
          })
          return mode
        })
        .value()
    },
    hideLoading() {
      if (this.hasPaymentError) {
        this.showLoading = false
      }
    },
    displayQrForm() {
      this.$nextTick(() => {
        this.$refs.popUpQrCode.$el.querySelector('.modal-body').innerHTML = ''
        this.qrElements.forEach(el => {
          this.$refs.popUpQrCode.$el.querySelector('.modal-body').appendChild(el)
        })
        this.$refs.popUpQrCode.$el.querySelector('.modal-body').addEventListener(
          'hide',
          function() {
            this.paymentSuccessCallback()
          }.bind(this),
          false
        )
      })
    },
    rOnHoldPaymentMethods(el, options, index) {
      return el('div', { attrs: { id: `onHoldPaymentMethodLevel-${index}` } }, options.title)
    },
    makeOnHoldPayment(provider) {
      let self = this
      self.showLoading = true
      let onHoldPayment = { is_paylater: false, is_cash_on_delivery: false }
      if (provider) {
        onHoldPayment[provider.reference_key] = true
        self.setOnHoldPaymentMode(onHoldPayment)
        self.onHoldPaymentCallback()
      }
    },
  },
  computed: {
    ...mapGetters([
      'getSalesPaymentModes',
      'getEppPaymentCodes',
      'getShowLoadingPopup',
      'getPaymentQrCode',
      'getErrors',
      'getAppStatus',
      'getAppLocationCountry',
      'getCountryList',
      'getCurrentSaleId',
    ]),
    ...mapGetters('eshop', ['getCartHasEpp']),
    processPaymentModes: function() {
      let self = this
      let paymentModes = []
      if (
        this._payment_methods_get_payment_modes() !== undefined &&
        this._payment_methods_get_payment_modes().list !== undefined
      ) {
        paymentModes = this._payment_methods_get_payment_modes().list
      }
      return _.chain(paymentModes)
        .cloneDeep()
        .map((mode, levelIndex) => {
          mode.payment_mode_provider = _.chain(mode.payment_mode_provider)
            .map(provider => {
              let fields = self.$helpers.getValue(provider, 'payment_mode_setting[0].setting_detail[0].fields')
              return {
                sale_id: self.saleId, // this.paymentData.sale_id
                pay_type: self.makePaymentData.payType,
                consignment_deposit_id: self.makePaymentData.consignmentDepositId,
                qr_code: provider.payment_mode_setting[0].qr_code,
                payment_mode_id: provider.payment_mode_setting[0].id,
                payment_mode_name: provider.name,
                payment_mode_code: provider.code,
                payment_is_popup_view: provider.is_popup_view,
                fields: fields
                  ? _.chain(fields)
                      .sortBy('order', 'asc')
                      .map(field => {
                        field.required = true
                        return field
                      })
                      .value()
                  : [],
              }
            })
            .value()
          return mode
        })
        .filter(this.canShowPaymentMode)
        .value()
    },
    canShowPaymentMode: vue => level => {
      if (
        vue.$appSettings.payment.eppPaymentFilter ||
        vue.$helpers.getValue(vue, 'getAppLocationCountry.countryId') ===
          (vue.getCountryList.find(country => country.code_iso_2.toLowerCase() === 'tw') || {}).id
      ) {
        return true
      }
      if (vue.$helpers.isSet(level, 'payment_mode_provider[0].payment_mode_code')) {
        return (
          (vue.getCartHasEpp === true &&
            vue.checkEppPayments === true &&
            vue.getEppPaymentCodes.includes(level.payment_mode_provider[0].payment_mode_code)) ||
          ((vue.getCartHasEpp === false || vue.checkEppPayments === false) &&
            !vue.getEppPaymentCodes.includes(level.payment_mode_provider[0].payment_mode_code))
        )
      } else {
        return false
      }
    },
    getMedium: function() {
      if (this.getAppStatus('esac') === true) {
        return 'esac_redemption'
      } else {
        return null
      }
    },
    getPaymentCallbackMeta() {
      let isThirdParty = this.getAppStatus('thirdPartyAppsCheckout') || this.getAppStatus('thirdPartyAppsResumePayment')
      let path = window.location.origin

      if (isThirdParty) {
        path = window.location.href.split('#')[0] + '/#'
      }
      path += this.$route.path

      let callBackUrl =
        (this.getAppStatus('esac') && [path, this.getCurrentSaleId].join('/') + '?cb=true') ||
        (this.getAppStatus('enrolment') && path.replace(/\/checkout/, '/complete')) ||
        (this.getAppStatus('thirdPartyAppsCheckout') && path.replace(/\/summary/, '/complete')) ||
        (this.getAppStatus('thirdPartyAppsResumePayment') && path.replace(/\/order-summary/, '/complete')) ||
        (this.getAppStatus('iToken') &&
          path.replace(/\/payment/, '/complete') + (this.enableInlinePaymentMode ? '?session=active' : '')) ||
        path.replace(/\/payment/, '/complete')

      return { payment_callback_metadata: JSON.stringify({ url: callBackUrl }) }
    },
    enableInlinePaymentMode() {
      return this.$appSettings.payment.inlinePaymentMode
    },
  },
  watch: {
    showLoading: {
      handler(to) {
        if (to && this.$refs.makingPaymentLoader !== undefined) {
          lottie.loadAnimation({
            container: this.$refs.makingPaymentLoader,
            renderer: 'svg',
            loop: true,
            animationData: this.lottieLoaderFile ? this.lottieLoaderFile : ConnectingLoader,
          })
        }
      },
      immediate: true,
    },
    showLoadingPopup() {
      this.showLoading = this.showLoadingPopup
    },
  },
})
</script>
