<template>
  <div>
    <b-row>
      <b-col cols="12" lg="6" class="mb-4">
        <b-card-title class="mb-4 text-black">{{ $t('Autoship.Section.ShippingInfo') }}</b-card-title>
        <shipping-method
          id="shippingMethod"
          hide-title
          address-style="box"
          enable-cross-country
          :wrapper-classes="[]"
          ref="shippingDetailInfo"
          v-model="deliveryModel"
          scope="eshopOrderReview"
          :container-class="['px-0']"
          :shipping-info="shippingInfo"
          :allow-save-shipping-address="false"
          shipping-method-form-field-row-size-classes="col-lg-12"
          data-qa-prefix="autoship-shipping"
        />
        <b-form-checkbox
          v-if="hasSameAsAddressOption"
          v-model="isSameAsShipping"
          class="mt-4"
          data-qa="autoship-shipping-same-as-shipping-address-checkbox"
        >
          <span class="c-pointer">{{ $t('Autoship.SameShippingAndBilling.Label') }}</span>
        </b-form-checkbox>
      </b-col>
      <!-- multiple shipping-method-delivery component cannot render together set delay to maintain accuracy -->
      <b-col cols="12" lg="6" v-show="!isSameAsShipping" class="mb-4" v-if="delayVisible">
        <b-card-title class="mb-4 text-black">{{ $t('Autoship.Section.BillingInfo') }}</b-card-title>
        <shipping-method-delivery
          address-style="box"
          :is-allowed-all-countries="true"
          :allow-save-shipping-address="false"
          :shipping-info="billingInfo"
          enable-all-call-code-option
          ref="billingAddressInfo"
          v-model="billingModel"
          shipping-method-form-field-row-size-classes="col-lg-12"
          class="eshop"
        />
      </b-col>
    </b-row>
    <b-row align-h="end">
      <b-col cols="auto" v-if="isUpdate">
        <b-button
          variant="outline-light"
          class="ml-3 px-4"
          @click="initializeUpdateForm()"
          data-qa="autoship-shipping-reset-btn"
        >
          {{ $t('Common.Reset') }}
        </b-button>
        <b-button
          variant="primary"
          class="ml-3 px-4"
          @click="updateSubscriptionAddresses()"
          data-qa="autoship-shipping-save-changes-btn"
        >
          {{ $t('Common.SaveChanges') }}
        </b-button>
      </b-col>
    </b-row>
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'
import _ from 'lodash'
import { mapMasterDataId } from '@/app/_global/mixins'
import ShippingMethodDelivery from '@/app/_global/components/blocks/ShippingMethodDelivery'
import ShippingMethod from '@/app/_global/components/blocks/ShippingMethod'

export default {
  name: 'Shipping',
  components: { ShippingMethodDelivery, ShippingMethod },
  props: ['isUpdate', 'currentSubscription'],
  data() {
    return {
      localCurrentSubscription: {},
      isSameAsShipping: true,
      deliveryModel: {},
      billingModel: {},
      shippingInfo: {},
      billingInfo: {},
      delayVisible: false,
      hasSameAsAddressOption: true,
    }
  },
  provide() {
    let self = this
    return {
      get _shipping_countries() {
        return self.getCountries
      },
      _self_pickup_load_stockist_address_list: self.generateStockistAddressLists,
    }
  },
  mounted() {
    let self = this
    this.resolveMasters.then(() => {
      self
        .loadMyAccountInfo()
        .then(() => {
          return self.initializeShippingData({
            member: self.getMyAccountMemberDetails,
            countryId: self.getAppLocationCountry.countryId,
            isPreferredEmail: self.getMyAccountIsPreferredContactType(self.preferredEmailId),
          })
        })
        .then(() => {
          if (!self.isUpdate) {
            self.loadShippingInfoFormData()
          } else {
            self.loadCountries()
            this.localCurrentSubscription = _.cloneDeep(this.currentSubscription)
            self.initializeUpdateForm()
          }
        })
    })
    window.setTimeout(function() {
      self.delayVisible = true
    }, 3000)
  },
  computed: {
    ...mapGetters([
      'getShippingData',
      'getMyAccountMemberDetails',
      'getAutoshipCountry',
      'getMyAccountIsPreferredContactType',
      'getCountries',
      'getAppLocationCountry',
      'getAutoshipShippingInfo',
      'getAutoshipBillingInfo',
      'getMemberDetails',
    ]),
    ...mapMasterDataId({
      PREFERRED_CONTACT: {
        preferredEmailId: 'EMAIL',
      },
      SALE_DELIVERY_METHOD: {
        shippingMethodWithoutShippingId: 'WITHOUT_SHIPPING',
        shippingMethodDeliveryId: 'DELIVERY',
        shippingMethodSelfCollectionId: 'SELF_PICKUP',
      },
    }),
  },
  methods: {
    ...mapActions('eshop', ['loadCart']),
    ...mapActions([
      'loadMyAccountInfo',
      'initializeShippingData',
      'loadStockistLocationAddressList',
      'setShippingInfo',
      'setBillingInfo',
      'updateAutoshipSubscription',
      'loadCountries',
    ]),
    loadShippingInfoFormData() {
      const staticAddressData = _.cloneDeep(this.getShippingData)

      if (_.isEmpty(this.getAutoshipShippingInfo) === false && _.isEmpty(this.getAutoshipBillingInfo) === false) {
        // Setup model data
        //  TODO: JACK REMOVE THIS 2 VARIABLE IF DONT HAVE ANY IMPACT
        this.deliveryModel = _.cloneDeep(this.getAutoshipShippingInfo)
        this.billingModel = _.cloneDeep(this.getAutoshipBillingInfo)

        this.isSameAsShipping = this.getAutoshipBillingInfo === this.getAutoshipShippingInfo

        // Merge saved autoship shipping info and billing info with local components.
        const baseRecipientData = {
          recipient_name: staticAddressData.recipient_name,
          recipient_mobile_country_code_id: staticAddressData.recipient_mobile_country_code_id,
          recipient_mobile_phone_number: staticAddressData.recipient_mobile_phone_number,
        }

        this.shippingInfo = {
          member_addresses: _.cloneDeep(staticAddressData.member_addresses),
          selected_address: this.$helpers.getValue(this.deliveryModel, 'recipient_addresses[0]', {}),
          ..._.cloneDeep(baseRecipientData),
          ...this.deliveryModel,
          validated: false,
        }
        this.billingInfo = {
          member_addresses: _.cloneDeep(staticAddressData.member_addresses),
          selected_address: this.$helpers.getValue(this.billingModel, 'recipient_addresses[0]', {}),
          ..._.cloneDeep(baseRecipientData),
          ...this.billingModel,
          validated: false,
        }
      } else {
        // Set default sales delivery method if no sales delivery method found
        this.shippingInfo = _.chain(staticAddressData)
          .cloneDeep()
          .merge({ sale_delivery_method: this.shippingMethodDeliveryId })
          .value()
        this.billingInfo = _.cloneDeep(staticAddressData)
      }
    },
    initializeUpdateForm() {
      let subscription = this.localCurrentSubscription
      this.isSameAsShipping = _.isEqual(subscription.shipping_address, subscription.billing_address)

      this.setAddressInfoInPromise('shippingInfo')
      this.setAddressInfoInPromise('billingInfo')
    },
    async setAddressInfoInPromise(type) {
      return new Promise(resolve => {
        if (type === 'shippingInfo') {
          this.shippingInfo = this.buildAddressInfo('shippingInfo')
        } else if (type === 'billingInfo') {
          this.billingInfo = this.buildAddressInfo('billingInfo')
        }
        resolve()
      })
    },
    buildAddressInfo(type) {
      const tempAddressData = _.cloneDeep(this.getShippingData)
      let subscription = this.localCurrentSubscription
      let memberAddresses = tempAddressData.member_addresses
      let recipient = {
        recipient_name: tempAddressData.recipient_name,
        recipient_mobile_country_code_id: tempAddressData.recipient_mobile_country_code_id,
        recipient_mobile_phone_number: tempAddressData.recipient_mobile_phone_number,
      }
      if (type === 'shippingInfo') {
        recipient = { ...recipient, ...subscription.shipping_address }
      } else if (type === 'billingInfo') {
        recipient = { ...recipient, ...subscription.billing_address }
      }

      return {
        member_addresses: [...memberAddresses],
        ...recipient,
        selected_address: this.$helpers.getValue(recipient, 'recipient_addresses[0]', {}),
      }
    },
    generateStockistAddressLists(payload) {
      return this.loadStockistLocationAddressList({
        country_id: this.getAutoshipCountry,
        location_id: payload.location_id,
      })
    },
    async updateSubscriptionAddresses() {
      if (await this.validateAndSubmit()) {
        let shipping = this.$refs['shippingDetailInfo'].getData()
        let billing = {}

        if (this.isSameAsShipping) {
          billing = shipping
        } else {
          billing = this.$refs['billingAddressInfo'].getData()
        }

        let payload = {
          user_id: this.getMemberDetails.user_id,
          updated_by_application_user_id: this.getMemberDetails.user_id,
          country_code: this.currentSubscription.country_code,
          subscription_id: this.currentSubscription.subscription_id,
          shipping_address: shipping,
          billing_address: billing,
        }

        this.updateAutoshipSubscription(payload).then(response => {
          if (response.data !== undefined) {
            this.localCurrentSubscription = response.data
            this.$router.push({ name: 'AutoshipDetail' })
            this.$swal({
              title: this.$t('Autoship.Edit.SavedSuccess'),
              type: 'success',
              timer: '2100',
              showConfirmButton: false,
            })
          } else {
            this.$swal({
              title: this.$t('Autoship.Popup.UpdateFail.msg'),
              type: 'error',
            })
          }
        })
      } else {
        this.$swal({
          title: this.$t('Common.Error.RequiredField'),
          type: 'error',
        })
      }
    },
    validateDynamicFields(field) {
      let self = this

      if (field === 'shippingDetailInfo') {
        return self.$refs['shippingDetailInfo'].validate().then(valid => {
          if (valid) {
            let data = self.$refs['shippingDetailInfo'].getData()
            data.sale_delivery_method = this.shippingInfo.sale_delivery_method
            data.validated = true

            self.setShippingInfo(data)
            if (self.isSameAsShipping) {
              self.setBillingInfo(data)
            }
          } else {
            self.$scrollTo('[name="' + self.$refs['shippingDetailInfo'].$validator.errors.items[0].field + '"]')
          }
          return valid
        })
      } else if (field === 'billingAddressInfo') {
        return this.$refs['billingAddressInfo'].$validator.validateAll().then(valid => {
          if (valid) {
            let data = self.$refs['billingAddressInfo'].getData()
            data.sale_delivery_method = self.shippingMethodDeliveryId
            data.validated = true

            self.setBillingInfo(data)
          } else {
            self.$scrollTo('[name="' + self.$refs['billingAddressInfo'].$validator.errors.items[0].field + '"]')
          }
          return valid
        })
      }
    },
    validateAndSubmit() {
      let validators = [this.validateDynamicFields('shippingDetailInfo')]
      if (this.isSameAsShipping !== true) {
        validators.push(this.validateDynamicFields('billingAddressInfo'))
      }
      return Promise.all([...validators]).then(async function(validation) {
        return validation.indexOf(false) === -1 && validation.indexOf(undefined) === -1
      })
    },
  },
  watch: {
    'shippingInfo.sale_delivery_method': {
      handler(val) {
        // when user select self collection method, show billing address component
        if (val === this.shippingMethodSelfCollectionId) {
          this.isSameAsShipping = false
          // Remove same as shipping check box
          this.hasSameAsAddressOption = false
        } else {
          this.hasSameAsAddressOption = true
        }
      },
    },
  },
}
</script>
