<template>
  <cr-form
    class="login-form"
    ref="loginForm"
    show-error
    validate-trigger="onBlur"
    @submit="login"
    @failed="onFormFailed"
  >
    <cr-field
      v-model="formData.phoneNo"
      name="phoneNo"
      type="tel"
      label=""
      placeholder="请填写您的手机号"
      :rules="validOptions[0]"
    />
    <cr-field
      v-if="captchaShow"
      class="send-sms-field"
      v-model="formData.captcha"
      name="captcha"
      type="digit"
      label=""
      placeholder="请填写图片验证码"
      :rules="validOptions[1]"
    >
      <template slot="button">
        <img :src="captchaUrl" @click="getCaptcha()" class="captchaUrl" />
      </template>
    </cr-field>
    <cr-field
      class="send-sms-field"
      v-model="formData.verifyCode"
      name="verifyCode"
      type="tel"
      label=""
      placeholder="请填写验证码"
      :rules="validOptions[1]"
    >
      <template slot="button">
        <a
          href="javascript:;"
          :style="vcStyles"
          :class="['login-form-send', { 'not-allow': noAllowSend || showCount }]"
          ref="sendVcode"
        >
          {{ captchaBtnText }}
        </a>
      </template>
    </cr-field>
    <cr-button :color="btnColor" :style="btnStyles" shape='circle' block native-type="submit" class="login-form-submit">
      {{ btnTxt }}
    </cr-button>
  </cr-form>
</template>

<script>
import Vue from 'vue';
import Storage from '@/service/localStorage.service.ts';
import Cookies from '@/service/cookieStorage.service.ts';
import { isPhone } from '@/service/utils.service.ts';
import Api from './api/api.ts';
import config from '@/config/index';

const validOptions = [
  [
    { required: true, message: "请填写您的手机号" },
    { validator: isPhone, message: "请填写正确的手机号码" }
  ],
  [{ required: true, message: "请填写验证码" }]
];
let timer = null;
let sa = null;

export default {
  name: "KALoginForm",
  props: {
    btnTxt: String,
    btnColor: {
      type: String,
      default: '#000'
    },
    btnImage: String,
    vcBgColor: String,
    registerFrom: String,
  },
  data() {
    return {
      showCount: false,
      count: null,
      captchaUrl: "",
      captchaShow: false,
      gtShow: false,
      captchaId: "",
      gt: {
        clientType: "h5",
        verifyType: "gt",
        geetest_challenge: "",
        geetest_validate: "",
        geetest_seccode: "",
        phoneNo: ""
      },
      uniqueKey: "",
      formData: {
        phoneNo: "",
        verifyCode: "",
        captcha: ""
      },
      validOptions
    };
  },
  computed: {
    noAllowSend() {
      return !isPhone(this.formData.phoneNo);
    },
    captchaBtnText() {
      return this.showCount ?  `剩余${this.count}秒` : '获取验证码';
    },
    btnStyles() {
      return this.btnImage ? {
        background: `url(${this.btnImage}) no-repeat 0 0 / 100%`,
      } : {};
    },
    vcStyles() {
      return { backgroundColor: this.vcBgColor };
    }
  },
  mounted() {
    require('./jy/jy.ts');
    this.initSa();
    this.verifyMode();
  },
  methods: {
    initSa() {
      sa = require('sa-sdk-javascript');
      //神策数据埋点
      sa.init({
        server_url: config.shenceUrl,
        heatmap: {
            //是否开启点击图，默认 default 表示开启，自动采集 $WebClick 事件，可以设置 'not_collect' 表示关闭
            clickmap:'default',
            //是否开启触达注意力图，默认 default 表示开启，自动采集 $WebStay 事件，可以设置 'not_collect' 表示关闭
            scroll_notice_map:'default',
            //判断外层是否有 App 的 SDK ，如果有的话，会往 App 的 SDK 发数据。如果没有，就正常发送数据。
            // use_app_track: true,
        },
        show_log: process.env.NODE_ENV !== 'production'
      });
      //添加公共属性
      sa.registerPage({platformType:'H5'});
      this.$nextTick(() => {
        sa.quick("autoTrackSinglePage");
      });
    },
    async verifyMode() {
      const res = await Api.verifyMode(this.gt.clientType, this.formData.phoneNo);
      this.uniqueKey = res?.uniqueKey;
      if (res?.verifyType === 'gt') {
        this.getJyParam(res);
      } else {
        this.getCaptcha();
      }
    },
    getJyParam({ gt, challenge, success }) {
      var vm = this;
      initGeetest(
        {
          width: "100%",
          gt: gt,
          challenge: challenge,
          offline: !success,
          product: "bind"
        },
        function(captchaObj) {
          vm.$refs.sendVcode.addEventListener('click', function() {
            if (!isPhone(vm.formData.phoneNo)) {
              vm.$notify({ type: "warning", message: "请填写正确的手机号码" });
              return;
            }
            if (vm.showCount) return;
            captchaObj.verify();
          });
          captchaObj.onSuccess(function() {
            var result = captchaObj.getValidate();
            vm.gt.geetest_challenge = result.geetest_challenge;
            vm.gt.geetest_validate = result.geetest_validate;
            vm.gt.geetest_seccode = result.geetest_seccode;
            vm.getCode(captchaObj);
          });
          captchaObj.onError(function() {
            vm.$toast("尝试过多，请点击重试");
          });
        }
      );
    },
    async getCaptcha() {
      this.captchaShow = true;
      const res = await Api.getCaptcha();
      ({ image: this.captchaUrl, imageId: this.captchaId } = res);
    },
    async getCode(captchaObj) {
      if (!isPhone(this.formData.phoneNo)) {
        this.$notify({ type: "warning", message: "请填写正确的手机号码" });
        return;
      }
      if (timer) return;
      try {
        await this.sendCode();
        this.smsCount();
        this.$notify({ type: "success", message: "短信验证码已发送，请注意查收" });
      } finally {
        this.resetJyState(captchaObj);
      }
    },
    async sendCode() {
      const { phoneNo, captcha } = this.formData;
      if (this.captchaShow) {
        await Api.sendVcode(phoneNo, captcha, this.captchaId);
      } else {
        await Api.sendGtVcode({ ...this.gt, phoneNo: phoneNo });
      }
    },
    smsCount() {
      this.showCount = true;
      this.count = 60;
      timer = setInterval(() => {
        if (this.count > 0 && this.count <= 60) {
          this.count--;
        } else {
          this.showCount = false;
          clearInterval(timer);
          timer = null;
        }
      }, 1000);
    },
    resetJyState(captchaObj) {
      if(captchaObj) captchaObj.reset();
    },
    async login() {
      let le_is_login_success = false;
      try {
        const { phoneNo, verifyCode } = this.formData;
        const user = await Api.fastLogin(phoneNo, verifyCode, null, this.uniqueKey, this.registerFrom);
        this.saveInfo(user);
        le_is_login_success = true;
        this.goNext();
      } finally {
        sa.track('LoginEvent', {
          le_login_action: '注册/登录',
          le_login_type: '验证码登录',
          le_is_login_success,
          le_channel_code: this.registerFrom,
        });
      }
    },
    async goNext() {
      const extData = { redirectURL: null, productId: 1 };
      const params = {
        key: 'xyqb',
        target: 'cashTarget4',
        currentPage: 'login'
      };
      const { transition } = await Api.goNext(params);
      window.location.replace(
        transition + '?phoneNo=' + Storage.get('phoneNo') + '&protocol=' + window.location.protocol + '&token=' + Storage.get('token') + (extData ? '&extData=' + btoa(JSON.stringify(extData)) : '')
      );
    },
    onFormFailed(errorInfo) {
      const { errors } = errorInfo;
      this.$notify({ type: "warning", message: errors[0].message });
    },
    saveInfo({ token, phoneNo, uuid }) {
      Storage.set('token', token);
      Cookies.set('phoneNo', phoneNo);
      if (uuid) {
        Cookies.set('userid', uuid);
        sa.login(uuid);
      }
    }
  },
};
</script>

<style lang="less">
@import './jy/jy.less';
.login-form {
  padding: 0 20px;
  width: 100%;
  .cr-field--error-message {
    display: none;
  }
  .cr-cell {
    &__value {
      overflow: initial;
    }
    &-group {
      &::after {
        display: none;
      }
    }
    background-color: #fff;
    border-radius: 8px;
    margin-bottom: 12px;
    align-items: center;
    padding: 12.5px 16px;
    &::after {
      display: none;
    }
    &__title {
      color: #333333;
      display: flex;
      align-items: center;
    }
  }
  &-btn {
    width: 90px;
    position: relative;
  }
  &-send {
    padding: 5px 10px 4px;
    border-radius: 8px;
    background-color: #97d5ff;
    color: #fff;
    &.not-allow {
      background-color: #eaeaea !important;
      color: #999;
    }
  }
  &-submit {
    height: 50px !important;
    border-radius: 8px !important;
    border: 0 !important;
  }
}
.send-sms-field {
  padding: 8px 6px 8px 15px !important;
}
</style>
