<template>
  <div class="comp-certificate-info">
    <div class="device-list">
      <i v-if="device.showReadCard && form.type === 'IDCARD'" class="icon-device-card" @click="getCertData"/>
    </div>
    <el-form ref="formRef" :model="form" :rules="formRules" size="small" label-position="top">
      <el-row :gutter="40">
        <el-col :span="12">
          <el-form-item label="证件类型" prop="type">
            <el-select v-model="form.type" placeholder="请选择证件类型" clearable filterable @change="onTypeChange">
              <el-option
                v-for="item in dict.certType"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <template v-if="form.type !== ''">
        <el-row :gutter="40">
          <el-col :span="24">
            <el-form-item v-if="form.photoUrls && form.photoUrls.length > 0" label="上传证件照片" prop="photoUrls" class="cci-form-item">
              <template v-if="form.type === 'IDCARD'">
                <el-row :gutter="18">
                  <el-col :span="6" style="margin-right:40px">
                    <comp-certificate-upload
                      v-model="form.photoUrls[0].url"
                      :limit="1"
                      :certs="[form.photoUrls[0]]"
                      :bg-img-url="positiveBgUrl"
                      :face="true"
                      desc="请上传人像面"
                      @on-cert="data => formatCardInfo(data, CERT_FRONT)"
                      @take-photo-success="(data)=>takePhotoSuccess(data, 0)"
                      @input="uploadAutoValidate"
                    />
                  </el-col>
                  <el-col :span="6">
                    <comp-certificate-upload
                      v-model="form.photoUrls[1].url"
                      :limit="1"
                      :certs="[form.photoUrls[1]]"
                      :bg-img-url="negativeBgUrl"
                      :face="false"
                      desc="请上传国徽面"
                      @on-cert="data => formatCardInfo(data, CERT_BACK)"
                      @take-photo-success="(data)=>takePhotoSuccess(data, 1)"
                      @input="uploadAutoValidate"
                    />
                  </el-col>
                </el-row>
              </template>
              <template v-else>
                <el-row>
                  <el-col v-for="(item, index) in form.photoUrls" :span="4" :key="item.id">
                    <comp-certificate-upload
                      v-model="item.url"
                      :limit="maxCertImgCount"
                      :certs="[form.photoUrls[0]]"
                      :bg-img-url="positiveBgUrl"
                      desc="请上传证件照片"
                      card-type="other"
                      @take-photo-success="(data)=>takePhotoSuccess(data)"
                      @input="uploadAutoValidate"
                      @on-success="onUploadItemSuccess(index)"
                      @on-del="onUploadItemDel(index)"/>
                  </el-col>
                </el-row>
              </template>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <div class="cci-upload-tips">文件类型为图片文件，扩展名要求使用小写字母，允许支持的照片格式包括bmp、jpg/jpeg、png，小于500K</div>
          </el-col>
        </el-row>
      </template>
      <el-row :gutter="40">
        <el-col :span="12">
          <el-form-item label="证件号码" prop="no">
            <el-input v-model="form.no" placeholder="请输入证件号码" clearable maxlength="50" @blur="() => (form.no = form.no.toUpperCase())" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="证件地址" prop="address">
            <el-input v-model="form.address" placeholder="请输入证件地址" clearable maxlength="50"/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="40">
        <el-col :span="12">
          <el-form-item label="证件起始时间" prop="certEffectiveDate">
            <!-- 日期 -->
            <el-date-picker v-model="form.certEffectiveDate" :picker-options="startTimePickerOptions" :editable="false" type="date" placeholder="请选择证件有效期" clearable value-format="yyyy-MM-dd"/>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="通讯地址" prop="connectAddress">
            <el-input v-model="form.connectAddress" placeholder="请输入通讯地址" clearable maxlength="50"/>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="证件有效期" prop="validDate">
            <!-- 长期 -->
            <el-input v-if="form.validDate && form.validDate.length === 2" v-model="form.validDate" :readonly="true" placeholder="请填写证件有效期" clearable maxlength="2" @change="handleValidDateChange" />
            <!-- 日期 -->
            <el-date-picker v-else v-model="form.validDate" :picker-options="pickerOptions" :editable="false" type="date" placeholder="请选择证件有效期" clearable value-format="yyyy-MM-dd"/>
            <!-- 是否长期有效 -->
            <el-checkbox v-model="longTerm" @change="handleChangeValidData">长期有效</el-checkbox>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </div>
</template>

<script>
import dayjs from 'dayjs'
import bridge, { isInApp } from '@/utils/bridge'
import { mapGetters } from 'vuex'
import { validId } from '@/utils/validate'
import deviceService from '@/components/Device/service'
import { FIRM } from '@/store/modules/user'
import CompCertificateUpload from '@/components/CompCertificateUpload'
import positiveBgUrl from '@/assets/image/id_positive@2x.png'
import negativeBgUrl from '@/assets/image/id_negative@2x.png'

let gid = 0

// 证件信息正面
const CERT_FRONT = 'CERT_FRONT'
// 证件信息背面
const CERT_BACK = 'CERT_BACK'

export default {
  name: 'CompCertificateInfo',
  components: {
    CompCertificateUpload
  },
  props: {
    data: {
      type: Object,
      default: () => ({})
    },
    maxCertImgCount: {
      type: Number,
      default: 2
    }
  },
  data() {
    const checkphotoUrlsForId = (rule, value, callback) => {
      if (!Array.isArray(this.form.photoUrls) || this.form.photoUrls.length === 0) {
        callback(new Error('请上传人像面'))
      } else if (this.form.photoUrls[0].url.id === null) {
        callback(new Error('请上传人像面'))
      } else if (this.form.photoUrls[1].url.id === null) {
        callback(new Error('请上传国徽面'))
      } else {
        callback()
      }
    }
    const checkphotoUrlsForOther = (rule, value, callback) => {
      if (!Array.isArray(this.form.photoUrls) || this.form.photoUrls.length === 0) {
        callback(new Error('请上传证件图片'))
      } else if (this.form.photoUrls[0].url.id === null) {
        callback(new Error('请上传证件图片'))
      } else {
        callback()
      }
    }
    const checkphotoUrls = (rule, value, callback) => {
      if (this.form.type === 'IDCARD') {
        checkphotoUrlsForId(rule, value, callback)
      } else {
        checkphotoUrlsForOther(rule, value, callback)
      }
    }
    const checkNo = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入证件号码'))
      } else if (this.form.type === 'IDCARD' && !validId(value)) {
        callback(new Error('证件号码格式不正确'))
      } else {
        callback()
      }
    }
    return {
      CERT_FRONT,
      CERT_BACK,
      showDialog: false,
      form: {
        type: '',
        photoUrls: [],
        no: '',
        address: '',
        validDate: '',
        certEffectiveDate: '',
        connectAddress: ''
      },
      formRules: {
        type: [
          { required: true, message: '请选择证件类型', trigger: 'change' }
        ],
        photoUrls: [
          { required: true, validator: checkphotoUrls, trigger: 'change' }
        ],
        no: [
          { required: true, validator: checkNo, trigger: 'blur' }
        ],
        address: [
          { required: true, message: '请输入证件地址', trigger: 'blur' }
        ],
        certEffectiveDate: [
          { required: true, message: '请选择证件起始时间', trigger: 'change' }
        ],
        validDate: [
          { required: true, message: '请选择证件有效期', trigger: 'change' }
        ]
      },
      longTerm: false,
      positiveBgUrl,
      negativeBgUrl
    }
  },
  computed: {
    ...mapGetters(['dict', 'device']),
    /**
     * 时间选择器的选项（当前天之前不让选中）
     */
    pickerOptions() {
      return {
        disabledDate(time) {
          return time.getTime() < dayjs().startOf('date').valueOf()
        }
      }
    },
    /**
     * 时间选择器的选项（当前天之前不让选中）
     */
    startTimePickerOptions() {
      return {
        disabledDate(time) {
          return time.getTime() >= dayjs().endOf('date').valueOf()
        }
      }
    }
  },
  watch: {
    data() {
      this.updateInternalData()
    }
  },

  created() {
    this.init()
  },
  methods: {
    // 获取证件信息
    getCertData() {
      if (this.form.type !== 'IDCARD') {
        return
      }
      // 如果当前在app中
      if (isInApp) {
        return new Promise((resolve, reject) => {
          bridge.readIDCardByOTG(data => {
            data.gender = data.gender === '男' ? '1' : '2'
            this.formatCardInfo(data)
            this.validate()
            resolve()
          })
        })
      }
      // 设备回调
      let deviceCallback
      // 如果当前是卡尔的
      if (this.device.firm === FIRM.KT) {
        deviceCallback = deviceService.readKtCardEx()
      } else {
        deviceCallback = deviceService.readIntegratedCard()
      }
      return deviceCallback.then(data => {
        this.formatCardInfo(data)
        this.validate()
      }).catch(err => {
        this.$message.error(err)
      })
    },

    /**
     * 格式化身份证证件信息
     * @param data 读取的信息
     */
    formatCardInfo(data, type = '') {
      // 如果当前是证件信息背面（国徽面）
      if (!type || type === CERT_BACK) {
        // 过期时间
        const expireDate = dayjs(data.expireDate, 'YYYYMMDD')
        // 开始时间
        const effectDate = dayjs(data.effectDate, 'YYYYMMDD')
        // 如果当前是非长期身份证
        if (expireDate.isValid()) {
          if (expireDate.isBefore(dayjs().startOf('date'))) {
            this.$message.error('当前身份证已过期，请注意更换')
            data.expireDate = ''
          } else {
            data.expireDate = expireDate.format('YYYY-MM-DD')
          }
        }
        // 设置身份证生效时间
        data.certEffectiveDate = effectDate.format('YYYY-MM-DD')
        this.form.validDate = data.expireDate
        this.form.certEffectiveDate = data.certEffectiveDate
        this.longTerm = data.expireDate === '长期'
      }
      // 如果当前是证件信息正面（人像面）
      if (!type || type === CERT_FRONT) {
        this.form.no = data.idNum
        this.form.address = data.address
        this.$emit('read-cert', data)
      }
    },

    init() {
      this.updateInternalData()
    },
    updateInternalData() {
      if (typeof this.data === 'object' && this.data !== null) {
        // 如果当前是长期
        this.longTerm = this.form.validDate === '长期'
        this.form.type = this.data.type || this.getDefaultType()
        this.form.photoUrls = this.data.photoUrls || this.getDefaultPhotoUrls()
        this.form.no = this.data.no || ''
        this.form.address = this.data.address || ''
        this.form.validDate = this.data.validDate || ''
        this.form.connectAddress = this.data.connectAddress || ''
      } else {
        this.form.type = this.getDefaultType()
        this.form.photoUrls = this.getDefaultPhotoUrls()
        this.form.no = ''
        this.form.address = ''
        this.form.validDate = ''
        this.form.connectAddress = ''
      }
    },
    getDefaultType() {
      return 'IDCARD'
    },
    getDefaultPhotoUrls() {
      if (this.form.type === 'IDCARD') {
        return [
          this.makeUploadDataTemplate(),
          this.makeUploadDataTemplate()
        ]
      }
      return [this.makeUploadDataTemplate()]
    },

    // 高拍仪拍照上传成功回调
    // index=0正面, index=1反面
    takePhotoSuccess(data, index) {
      if (data.length <= 0) {
        return
      }
      // 如果当前是身份证
      if (typeof index === 'number') {
        this.form.photoUrls.splice(index, 1, {
          id: gid++,
          url: {
            url: data[0].accessUrl,
            id: data[0].uuid
          }
        })
      } else {
        this.form.photoUrls = data.map(item => {
          return {
            id: gid++,
            url: {
              url: item.accessUrl,
              id: item.uuid
            }
          }
        })
      }
    },

    // 上传图片变化后自动校验
    uploadAutoValidate() {
      this.validatePhoto()
    },
    // 校验图片
    validatePhoto() {
      if (this.$refs.formRef) {
        this.$nextTick(() => {
          this.$refs.formRef.validateField('photoUrls')
        })
      }
    },

    // 上传成功自动添加空上传控件
    onUploadItemSuccess(index) {
      if (this.form.photoUrls.length >= this.maxCertImgCount) {
        return
      }
      // 最后一个控件上传成功后，添加新的
      if (index === this.form.photoUrls.length - 1) {
        this.form.photoUrls.push(this.makeUploadDataTemplate())
      }
    },
    // 删除上传控件
    onUploadItemDel(index) {
      if (this.form.photoUrls.length <= 1) {
        return
      }
      this.form.photoUrls.splice(index, 1)
      this.addPendingUploadItem()
    },
    // 添加待上传控件
    addPendingUploadItem() {
      if (this.form.photoUrls[this.form.photoUrls.length - 1].url.id !== null) {
        this.form.photoUrls.push(this.makeUploadDataTemplate())
      }
    },

    // 上传控件数据模板
    makeUploadDataTemplate() {
      return {
        id: gid++,
        url: {
          id: null,
          url: ''
        }
      }
    },

    onTypeChange() {
      this.form.photoUrls = this.getDefaultPhotoUrls()
      // 如果当前选择的是户口本，将则过期时间替换成长期
      this.form.validDate = this.form.type === 'HOUSEHOLD' ? '长期' : this.form.validDate
      this.validatePhoto()
    },

    // 校验
    async validate(isErrorAnchor = false) {
      try {
        await this.$refs.formRef.validate()
        return true
      } catch (e) {
        if (isErrorAnchor) {
          this.$refs.formRef.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
        }
        let temp = {
          anchor: () => {
            this.$refs.formRef.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
            temp = null
          }
        }
        throw temp
      }
    },
    // 获取数据
    getFormData() {
      return {
        type: this.form.type,
        no: this.form.no,
        address: this.form.address,
        validDate: this.form.validDate,
        certEffectiveDate: this.form.certEffectiveDate,
        connectAddress: this.form.connectAddress,
        photoUrls: this.form.photoUrls
      }
    },
    // 获取待缓存数据
    getPendingCacheData() {
      return this.getFormData()
    },
    /**
     * 当前长期选项改变时
     */
    handleChangeValidData() {
      this.form.validDate = this.longTerm ? '长期' : ''
    },
    /**
     * 日期改变时
     */
    handleValidDateChange() {
      // 如果当前是清空操作
      if (!this.form.validDate) {
        this.longTerm = false
      }
    },

    /**
     * 清空校验值
     */
    clearValidate() {
      this.$refs.formRef.clearValidate()
    }
  }
}
</script>

<style lang="scss">
.comp-certificate-info {
  position: relative;
  .device-list {
    position: absolute;
    top: -50px;
    right: 0;
  }
  .icon-device-card,
  .icon-device-video {
    margin-left: 16px;
  }
  .cci-upload-tips {
    margin-bottom: 22px;
    font-size: 12px;
    color: rgba(132,133,138,0.7);
  }
  .cci-form-item {
    margin-bottom: 10px;
    .el-form-item__error {
      top: calc(100% + 24px);
    }
  }
}
</style>
