<template>
  <div class="x-login-sms-code">
    <FormItem>
      <ElInput ref="input" v-model="model.smsCode" placeholder="请输入验证码" maxlength="6">
        <template v-slot:suffix>
          <ElButton @click="sendSmsCode"
                    :loading="loading"
                    :disabled="disabled"
                    class="x-login-mobile-number__sms"
                    type="text">
            {{smsCodeButtonText}}
          </ElButton>
        </template>
      </ElInput>
    </FormItem>
    <FormItem v-if="showImageVerify">
      <ElInput v-model="model.imageCode" @change="handleImageCodeChange" placeholder="请输入图形验证码" maxlength="4">
        <template v-slot:suffix>
          <div @click="updateVerifyUrl" class="x-login-sms__code">
            <img :src="verifyUrl" alt="">
          </div>
        </template>
      </ElInput>
    </FormItem>
    <FormItem class="x-login__holder-wrapper" v-else>
      <ElInput class="x-login__holder"></ElInput>
    </FormItem>
  </div>
</template>

<script>
import {
  FormItem,
  Input as ElInput,
  Button as ElButton,
  Notification
} from 'element-ui';
import {uuid} from '@newpearl/utils/lib/util';
import {stringify} from '@newpearl/utils/lib/url';
import {isMobilePhone} from '@newpearl/utils/lib/regex';

export default {
  components: {
    FormItem,
    ElInput,
    ElButton
  },
  inject: ['loginVm'],
  props: {
    phone: String,
    verify: String,
    buttonText: {
      type: String,
      default: '获取验证码'
    },
    reSendButtonText: {
      type: String,
      default: '重新获取'
    },
    limit: {
      type: Number,
      default: 60
    },
    sendSmsMethod: Function,
    value: String
  },
  data() {
    return {
      verifyUrl: '',
      verifyId: '',
      showImageVerify: false,
      model: {
        smsCode: this.value,
        imageCode: ''
      },
      counter: 0,
      disabled: false,
      loading: false,
      hasSend: false
    };
  },
  computed: {
    smsCodeButtonText() {
      return this.hasSend
        ? this.reSendButtonText + ' ' + (this.disabled ? this.counter : '')
        : this.buttonText;
    }
  },
  watch: {
    showImageVerify: {
      immediate: true,
      handler(val) {
        val && this.updateVerifyUrl();
      }
    },
    'model.smsCode'(val) {
      this.$emit('input', val);
    },
    value: {
      immediate: true,
      handler(val) {
        this.model.smsCode = val;
      }
    }
  },
  methods: {
    updateVerifyUrl() {
      const {verify} = this.loginVm;
      if (!verify) return null;
      this.verifyId = uuid();
      const query = {
        uuid: this.verifyId,
        w: 200,
        h: 80
      };
      this.verifyUrl = typeof verify === 'function'
        ? verify(query)
        : verify + '?' + stringify(query);
    },
    sendSmsCode() {
      if (!this.validate() || !this.sendSmsMethod) return;
      const {phone, model, verifyId} = this;
      this.loading = true;
      this.sendSmsMethod({
        phone: phone,
        imageCode: model.imageCode,
        imageUuid: verifyId,
        msgCode: 'SmsCodeEntryApply',
        reSendToken: ''
      }).then(res => {
        this.showImageVerify = false;
        this.disabled = true;
        this.counter = this.limit;
        this.hasSend = true;
        this.ticking();
      }).catch(e => {
        const msg = e.msg || e.message || '未知错误';
        Notification({
          message: msg,
          type: 'warning'
        });
        if (e.code === 506) {
          this.showImageVerify = true;
        }
        this.disabled = false;
      }).finally(_ => {
        this.loading = false;
      });
    },
    ticking() {
      this.timer = setTimeout(() => {
        --this.counter;
        if (this.counter > 0) {
          this.ticking();
        } else {
          this.disabled = false;
        }
      }, 1000);
    },
    validate() {
      const {phone, showImageVerify, model} = this;
      if (!isMobilePhone(phone)) {
        Notification({
          message: '请输入正确手机号',
          type: 'warning'
        });
        return false;
      }
      if (showImageVerify && model.imageCode.length < 4) {
        Notification({
          message: '请输入图形验证码',
          type: 'warning'
        });
        return false;
      }
      return true;
    },
    handleImageCodeChange() {
      const code = this.model.imageCode;
      if (code && code.length === 4) {
        this.sendSmsCode();
      }
    }
  },
  beforeDestroy() {
    this.timer && clearTimeout(this.timer);
  }
};
</script>
