<template>
  <b-row id="verification-area">
    <b-col :class="colClasses">
      <b-row :class="rowClasses">
        <b-col :class="labelClasses">
          <label>
            {{ $t('Common.PreferredContact') }}
          </label>
        </b-col>
        <b-col :class="controlClasses">
          <b-form-radio-group
            :disabled="Object.keys(preferredContactData.verification.post || {}).length > 0"
            @input="resetError('get_verification_code_failed')"
            :name="$t('Common.PreferredContact')"
            :class="fields[$t('Common.PreferredContact')]"
            :options="preferredContactOptions"
            v-model="preferredContactData.contact_info.preferred_contact_id"
          />
          <div class="guide-text text-medium mt-2">
            <span v-if="isOnBehalfEnrolment">
              {{ $t('Enrolment.SponsorVerificationMode.Label') }}
            </span>
            <span v-else>
              {{ $t('Enrolment.SelfVerificationMode.Label') }}
            </span>
          </div>
        </b-col>
        <b-col offset-lg="3" cols="9" :class="errorClasses">
          <field-errors :cerrors="errors" :cfields="fields" :name="$t('Common.PreferredContact')" />
        </b-col>
      </b-row>
      <b-row
        :class="rowClasses"
        v-if="preferredContactEmailId === preferredContactData.contact_info.preferred_contact_id"
      >
        <b-col :class="labelClasses">
          <label
            :class="{
              required: preferredContactEmailId === preferredContactData.contact_info.preferred_contact_id,
            }"
          >
            {{
              $t('Enrolment.Email.Label', {
                person: this.isOnBehalfEnrolment === 1 ? $t('Enrolment.Sponsors.Label') : $t('Enrolment.My.Label'),
              })
            }}
          </label>
        </b-col>
        <b-col :class="controlClasses">
          <b-form-input
            type="email"
            :name="$t('Enrolment.Email.Label', { person: 'My' })"
            :class="fields[$t('Enrolment.Email.Label', { person: 'My' })]"
            :disabled="Object.keys(preferredContactData.verification.post || {}).length > 0"
            @keydown.native="removeVerifications()"
            @input="resetError('get_verification_code_failed')"
            :state="getErrorsState('get_verification_code_failed') === false ? false : null"
            v-model="preferredContactData.contact_info.email"
            v-validate="
              preferredContactEmailId === preferredContactData.contact_info.preferred_contact_id ? 'required|email' : ''
            "
          />
        </b-col>
        <b-col offset-lg="3" cols="9" :class="errorClasses">
          <field-errors :cerrors="errors" :cfields="fields" :name="$t('Enrolment.Email.Label', { person: 'My' })" />
        </b-col>
      </b-row>
      <b-row
        :class="rowClasses"
        v-else-if="preferredContactPhoneId === preferredContactData.contact_info.preferred_contact_id"
      >
        <b-col :class="labelClasses">
          <label class="required">
            {{
              $t('Enrolment.MobilePhone.Label', {
                person:
                  preferredContactData.on_behalf_enrolment === 1
                    ? $t('Enrolment.Sponsors.Label')
                    : $t('Enrolment.My.Label'),
              })
            }}
          </label>
        </b-col>
        <b-col>
          <b-row>
            <b-col class="pr-0" :class="mobileCountryCodeControlClasses">
              <b-form-select
                :name="$t('Enrolment.MobileCountryCode.Labels', { person: '' })"
                :class="fields[$t('Enrolment.MobileCountryCode.Labels', { person: '' })]"
                @input="resetError('get_verification_code_failed')"
                @keydown.native="removeVerifications()"
                :disabled="Object.keys(preferredContactData.verification.post || {}).length > 0"
                v-model="preferredContactData.contact_info.mobile_1_country_code_id"
                v-validate="'required'"
                :options="getCountriesCallCode"
              />
            </b-col>
            <b-col>
              <b-input-group :prepend="countryCodePrefix(preferredContactData.contact_info.mobile_1_country_code_id)">
                <b-form-input
                  type="number"
                  placeholder="e.g. 127654321"
                  :name="$t('Enrolment.MobilePhone.Label', { person: '' })"
                  @input="resetError('get_verification_code_failed')"
                  @keydown.native="removeVerifications()"
                  :disabled="Object.keys(preferredContactData.verification.post || {}).length > 0"
                  :class="fields[$t('Enrolment.MobilePhone.Label', { person: '' })]"
                  v-model="preferredContactData.contact_info.mobile_1_num"
                  v-validate="'required|numeric'"
                />
              </b-input-group>
            </b-col>
            <b-col :class="errorClasses">
              <div v-if="errors.has($t('Enrolment.MobileCountryCode.Labels', { person: '' }))">
                {{ errors.first($t('Enrolment.MobileCountryCode.Labels', { person: '' })) }}
              </div>
              <div v-if="errors.has($t('Enrolment.MobilePhone.Label', { person: '' }))">
                {{ errors.first($t('Enrolment.MobilePhone.Label', { person: '' })) }}
              </div>
            </b-col>
          </b-row>
        </b-col>
      </b-row>
      <b-row :class="rowClasses" v-if="!disableContactVerification">
        <b-col offset-lg="3" cols="9" :class="errorClasses">
          <span
            v-show="!getErrorsState('get_verification_code_failed')"
            class="help invalid validated"
            v-for="(error, index) in getErrorsBreakup('get_verification_code_failed')"
            :key="index"
          >
            {{ error }}
          </span>
        </b-col>
        <b-col :class="verificationCodeControlClasses">
          <b-row>
            <b-col v-if="getContactVerificationMeta" class="pr-0" cols="4">
              <b-button
                block
                :title="getContactVerificationMeta.title"
                @click="getContactVerificationMeta.callback"
                :variant="getContactVerificationMeta.variant"
                :disabled="getContactVerificationMeta.disabled || false"
                class="d-flex align-items-center justify-content-center"
                v-bind="getContactVerificationMeta.type === 'verifyCode' ? { id: 'verification1' } : {}"
              >
                <b-spinner v-show="isLoading(getContactVerificationMeta.loader || '')" small class="mr-2" />
                <span>{{ getContactVerificationMeta.label }}</span>
              </b-button>
            </b-col>
            <b-col>
              <b-form-input
                id="verification2"
                :class="fields[$t('Common.Security.VerificationCode')]"
                :name="$t('Common.Security.VerificationCode')"
                @input="resetError('post_verification_code_failed')"
                :disabled="
                  Object.keys(preferredContactData.verification.post || {}).length > 0 ||
                    (preferredContactData.contact_info.email === '' &&
                      preferredContactData.contact_info.mobile_1_num === '' &&
                      preferredContactData.contact_info.mobile_1_country_code_id === '')
                "
                :placeholder="$t('Enrolment.EnterVerificationCode.Label')"
                v-model="preferredContactData.verification.code"
                v-b-tooltip.hover.top
                :title="$t('Common.Security.EnterVerificationCode')"
                v-validate="'required'"
              />
              <div :class="errorClasses" class="px-0">
                <field-errors
                  :cerrors="errors"
                  :cfields="fields"
                  :name="$t('Common.Security.VerificationCode')"
                ></field-errors>
              </div>
            </b-col>
          </b-row>
        </b-col>
        <b-col offset-lg="3" cols="9" :class="errorClasses">
          <span
            v-show="!getErrorsState('post_verification_code_failed')"
            class="help invalid validated"
            v-for="(error, index) in getErrorsBreakup('post_verification_code_failed')"
            :key="index"
          >
            {{ Array.isArray(error) ? error.toString() : error }}
          </span>
        </b-col>
        <span v-if="Object.keys(preferredContactData.verification.post || {}).length > 0" class="verified-text">
          {{ $t('Enrolment.VerifiedUTF.Label') }}
        </span>
      </b-row>
    </b-col>
  </b-row>
</template>
<script>
import { GeneralMixin, PhoneMixin } from '@/app/_global/mixins'
import FieldErrors from '@/elements/common/components/FieldErrors'
import { mapMasterDataId } from '@/app/_global/mixins'
import _ from 'lodash'
import appSettings from '@/config/app-settings'
import { mapGetters, mapActions } from 'vuex'

let data = {
  skip_contact_verification: false,
  contact_info: {
    preferred_contact_id: '',
    email: '',
    mobile_1_country_code_id: null,
    mobile_1_num: '',
  },
  verification: {
    code: '',
    get: {},
    post: {},
  },
}

export default {
  name: 'PreferredContact',
  inject: ['$validator'],
  mixins: [GeneralMixin, PhoneMixin],
  components: {
    FieldErrors,
  },
  props: {
    disableContactVerification: {
      type: Boolean,
      default: appSettings.enrolment.disableContactVerification,
    },
    value: {
      type: [Object, Boolean],
    },
    controlTooltip: {
      type: Function,
      default: () => ({}),
    },
    isOnBehalfEnrolment: {
      type: Number,
      default: 0,
    },
    colClasses: {
      type: Array,
      default: () => ['col-lg-9', 'col-12'],
    },
    rowClasses: {
      type: Array,
      default: () => ['controls-holder'],
    },
    labelClasses: {
      type: Array,
      default: () => ['section-label', 'col-lg-3'],
    },
    controlClasses: {
      type: Array,
      default: () => ['section-controls'],
    },
    mobileCountryCodeControlClasses: {
      type: Array,
      default: () => ['section-controls'],
    },
    verificationCodeControlClasses: {
      type: [Array, String],
      default: () => [],
    },
    errorClasses: {
      type: Array,
      default: () => ['section-controls-errors'],
    },
  },
  data: () => ({
    preferredContactData: data,
  }),
  computed: {
    ...mapMasterDataId({
      PREFERRED_CONTACT: {
        preferredContactEmailId: 'email',
        preferredContactPhoneId: 'phone',
        preferredContactOptions: 'options',
      },
    }),
    ...mapGetters({
      getErrors: 'getErrors',
      getErrorsBreakup: 'getErrorsBreakup',
      getErrorsState: 'getErrorsState',
      isLoading: 'isLoading',
    }),
    ...mapGetters('enrolment', {
      getVerificationResponse: 'getVerificationResponse',
      postVerificationResponse: 'postVerificationResponse',
    }),
    getContactVerificationMeta() {
      let verificationGetCount = Object.keys(this.preferredContactData.verification.get || {}).length
      let verificationPostCount = Object.keys(this.preferredContactData.verification.post || {}).length

      if (verificationGetCount === 0 && verificationPostCount === 0) {
        return {
          variant: 'success',
          loader: 'getEnrolmentCode',
          disabled: !this.canSendVerification,
          label: this.$t('Enrolment.SendCode.Label'),
          callback: this.getVerificationCode,
        }
      } else if (verificationGetCount > 0 && verificationPostCount === 0) {
        return {
          variant: 'success',
          type: 'verifyCode',
          loader: 'postEnrolmentCode',
          label: this.$t('Enrolment.VerifyCode.Label'),
          title: this.$t('Enrolment.Verification1.Info'),
          callback: this.postVerificationCode,
        }
      } else if (verificationGetCount > 0 && verificationPostCount > 0) {
        return {
          variant: 'danger',
          label: this.$t('Enrolment.Change.Button'),
          callback: this.removeVerifications,
        }
      }
      return false
    },
    canSendVerification() {
      let {
        email,
        mobile_1_num,
        mobile_1_country_code_id,
        preferred_contact_id,
      } = this.preferredContactData.contact_info
      let emailVerification =
        this.preferredContactEmailId === this.preferred_contact_id &&
        (email === '' || this.errors.has(this.$t('Enrolment.Email.Label', { person: '' })))
      let mobileVerification =
        this.preferredContactPhoneId === preferred_contact_id &&
        (mobile_1_num === '' ||
          mobile_1_country_code_id === '' ||
          this.errors.has(this.$t('Enrolment.MobilePhone.Label', { person: '' })))
      /**
       * Either of the condition is true means cannot request any verification
       * Jack reverse the return result is to match the computed value naming
       * Enhance this checking if have better solution
       */
      return !(emailVerification || mobileVerification || !this.getErrorsState('get_verification_code_failed'))
    },
  },
  watch: {
    preferredContactData: {
      async handler(to) {
        this.$set(to, 'skip_contact_verification', this.disableContactVerification)
        if (this.preferredContactData.contact_info.preferred_contact_id === '') {
          await this.resolveMasters
          this.preferredContactData.contact_info.preferred_contact_id = this.preferredContactEmailId
        }
        this.$emit('input', to)
      },
      deep: true,
    },
    value: {
      handler(to) {
        if (to) {
          this.preferredContactData = _.merge(to)
        } else {
          this.$validator.reset()
          this.preferredContactData = data
        }
      },
    },
  },
  methods: {
    ...mapActions(['resetError']),
    ...mapActions('enrolment', ['getCode', 'postCode', 'removeVerificationGetCode']),
    removeVerifications() {
      this.preferredContactData.verification.code = ''
      this.preferredContactData.verification.get = {}
      this.preferredContactData.verification.post = {}
    },
    getVerificationCode() {
      let query = {
        on_behalf_enrolment: this.isOnBehalfEnrolment,
      }
      if (this.preferredContactEmailId === this.preferredContactData.contact_info.preferred_contact_id) {
        query.type = 'email'
        query.verification_email = this.preferredContactData.contact_info.email
      } else {
        query.type = 'phone'
        query.call_code_id = this.preferredContactData.contact_info.mobile_1_country_code_id
        query.verification_mobile = this.preferredContactData.contact_info.mobile_1_num
      }
      this.getCode(query).then(() => {
        this.controlTooltip('show', ['verification1', 'verification2'])
        this.preferredContactData.verification.get = this.getVerificationResponse
        if (this.getVerificationResponse.verified === 1) {
          this.preferredContactData.verification.code = this.getVerificationResponse.code
          this.preferredContactData.verification.post = this.getVerificationResponse
          this.controlTooltip('hide', ['verification1', 'verification2'])
        }
      })
    },
    postVerificationCode() {
      if (!this.errors.has(this.$t('Common.Security.VerificationCode'))) {
        let query = {
          on_behalf_enrolment: this.isOnBehalfEnrolment,
        }
        if (this.preferredContactEmailId === this.preferredContactData.contact_info.preferred_contact_id) {
          query.type = 'email'
          query.verification_code = this.preferredContactData.verification.code
          query.verification_email = this.preferredContactData.contact_info.email
        } else {
          query.type = 'phone'
          query.verification_code = this.preferredContactData.verification.code
          query.call_code_id = this.preferredContactData.contact_info.mobile_1_country_code_id
          query.verification_mobile = this.preferredContactData.contact_info.mobile_1_num
        }
        this.postCode(query).then(() => {
          this.preferredContactData.verification.post = this.postVerificationResponse
          this.controlTooltip('hide', ['verification1', 'verification2'])
        })
      }
    },
  },
}
</script>
