<template>
  <div>
    <el-input
      ref="input"
      :placeholder="placeholder"
      :class="deviceName!=='tecsun'?'readerInput':'readerInput2'"
      :style="deviceName!=='tecsun'?{width: '310px'}:{width:'200px'}"
      clearable
      @blur="$emit('changePapersId')"
      @change="handleChange"
      v-model="tempValue">
      <div
        class="readCard"
        :style="{right:deviceName!=='tecsun'&&type!=='IC'?'-5px':'-5px'}"
        slot="suffix"
        :class="[{active:active},{loading:loading}]"
      >
        <div
          class="inner"
          @click="startRead">
          <i
            class="el-icon-loading svg-icon"
            v-if="loading"></i>
          <svg-icon
            icon-class="idCard"
            v-else /> {{ active?'停止':'读取' }}
        </div>

        <template v-if="type!=='IC'">
          <div
            v-if="deviceName==='donsee-100R'"
            class="inner"
            @click="getDonseeSBK">
            <svg-icon
              icon-class="idCard"
            /> 社保卡
          </div>
        </template>
      </div>
    </el-input>
    <SSCQrCodeReader
      ref="SSCQrCodeReader"
      @getSSCList="getSSCList"></SSCQrCodeReader>
  </div>
</template>

<script>
import getTecsun from '@/api/dsReaderApi'
import { readcard_xzx } from '@/api/xzxReaderApi'
import { getComName, getIccard, getIdInfo } from '@/api/ZTKReaderApi'
import { openDevice, readcard, closeDevice } from '@/api/HuashiReaderApi'
import { getReaderConnect, getReaderDisconnect, getReadCert } from '@/api/JinlunReaderApi'
import donsee from '@/api/donsee'
import { getServerConfig, isEmpty } from '@/utils'
import HuashiReaderWsApi from '@/api/HuashiReaderWsApi'

export default {
  data () {
    return {
      active: false,
      finished: false,
      tempValue: '',
      loading: false,
      comName: '', // 身份证阅读器端口号
      deviceName: this.$localStore.get('idDevice'), // 身份证阅读器类型。 zk 中控; hs 华视
      hsWsApi: null
    }
  },
  props: {
    type: {
      type: String,
      default: 'ID'
    },
    value: {
      type: [String, Object],
      default: ''
    },
    // 是否是用于支付的加密储值卡
    isPay: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default: '读取卡号'
    }
  },
  mounted () {
    if (this.deviceName === 'hs-ws') {
      this.hsWsApi = new HuashiReaderWsApi()
    }
  },
  methods: {
    // IC卡位数补全
    padString (e) {
      let lengthConfig = isEmpty(this.$localStore.get('ICCardLength')) ? getServerConfig('iccard_input_fill_length') : this.$localStore.get('ICCardLength')

      lengthConfig = isEmpty(lengthConfig) ? 10 : lengthConfig - 0

      console.log(`IC卡补齐设置：${typeof lengthConfig}, ${lengthConfig}`)

      const val = lengthConfig === 0 ? e : (e ? e.padStart(lengthConfig, '0') : '')

      return val
    },
    handleChange (e) {
      this.tempValue = e
      this.$emit('input', this.tempValue)
    },

    // 获取社保卡信息
    getSSCList (info) {
      this.$emit('input', info.idNum)
      this.$emit('change', { Name: info.name, IDNumber: info.idNum })
    },
    async startRead () {
      this.timer && clearTimeout(this.timer)

      if (this.deviceName !== 'donsee-100R') {
        this.tempValue = ''
        this.$emit('input', '')
      }

      if (this.active) {
        this.active = false
        this.loading = false
        this.finished = true
        this.cardSearchTimer && clearTimeout(this.cardSearchTimer)

        // 停止连续读取身份证信息
        if (this.deviceName === 'donsee-100R' && this.type === 'ID') {
          this.$store.dispatch('stopAutoReadIDCard')
        }
        return
      }

      this.finished = false

      if (this.deviceName === 'hs-ws') {
        this.handleHsWebSocket()
        return
      }

      // 东信EST-100R
      if (this.deviceName === 'donsee-100R') {
        this.handleDonsee100R()
        return
      }

      if (this.deviceName === 'tecsun') {
        this.handleTecsun()
        return
      }

      if (this.deviceName === 'donsee') {
        this.handleDonsee()
        return
      }

      if (this.deviceName === 'xzx') {
        this.getDevice()
        return
      }

      this.comName = await this.openDevice()

      if (!this.comName) {
        this.$message.error('未获取到设备')
        return
      }

      this.getDevice()
    },
    handleHsWebSocket () {
      if (!this.hsWsApi) {
        this.hsWsApi = new HuashiReaderWsApi()
      }
      if (this.hsWsApi.isConnected) {
        this.loading = true
        this.active = true
        this.hsWsApi.addMessageListener((res) => {
          if (res.data === 'failed to obtain ID card information') {
            this.$message.error('读取失败，请拿起卡片重试')
            this.getIdInfo()
            return
          }

          const alldata = res.data.split('|')
          console.log(alldata)

          if (alldata.length && alldata[0] === '卡认证失败') {
            this.$message.error('读取失败，请拿起卡片重试')
            this.loading = false
            this.active = false
            return
          }

          if (alldata.length >= 17) {
            this.$emit('change', { Name: alldata[3], IDNumber: alldata[8] })
            this.loading = false
            this.active = false
          }
        })

        this.hsWsApi.readIDCard(10 * 1000)
      } else {
        this.loading = false
        this.active = false
        this.hsWsApi.closeConnect()
        this.hsWsApi.connect((isConnected) => {
          if (isConnected) {
            // this.timer && clearTimeout(this.timer)
            this.handleHsWebSocket()
          } else {
            this.$message.error('身份证读卡器暂时无法使用，请检查；')
          }
        })
      }
    },
    handleTecsun () {
      this.loading = true
      this.active = true

      getTecsun(this).then(res => {
        if (!res) return
        console.log('%c [ res ]-148', 'font-size:13px; background:pink; color:#bf2c9f;', res)
        this.$emit('input', res.idNum)
        this.$emit('change', { Name: res.name, IDNumber: res.idNum })
      }).finally(() => {
        this.loading = false
        this.active = false
      })
    },
    // 东信EST-100，通过dll调用
    handleDonsee () {
      const dev = donsee()
      if (!dev) return
      const info = dev.readSfz() || dev.readSiCard()

      if (!info) {
        return this.$message.info('读取失败')
      }

      this.$emit('input', info.pCertNo)
      this.$emit('change', { Name: info.pName, IDNumber: info.pCertNo })
    },
    // 东信EST-100R，通过websocket调用
    handleDonsee100R () {
      this.loading = true
      this.active = true
      // 连续读取身份证信息
      this.$store.dispatch(this.type === 'ID' ? 'readIDCard' : 'readM1Card', this._uid)

      this.cardSearchTimer = setTimeout(() => {
        this.handleDonsee100R()
      }, 1000)
    },
    async openDevice () {
      this.loading = true
      this.active = true

      switch (this.deviceName) {
        case 'zk':
          return getComName().then(res => {
            if (res.data.ret === 0) {
              return res.data.data.name
            } else {
              return this.$localStore.get('mock') ? 'COM3' : ''
            }
          }).catch(e => {
            this.loading = false
            this.active = false
            return ''
          })
        case 'hs':
          await closeDevice()
          return openDevice().then(res => {
            if (res.data.resultFlag === 0) {
              return res.data
            } else {
              return ''
            }
          }).catch(e => {
            this.loading = false
            this.active = false
            return ''
          })
        case 'jl':
          return getReaderConnect().then(res => {
            if (res.resultFlag === 0) {
              return res.isCloud
            } else {
              return ''
            }
          }).catch(e => {
            this.loading = false
            this.active = false
            return ''
          })
      }
    },
    getDevice () {
      switch (this.type) {
        case 'ID':
          if (this.deviceName === 'zk') {
            getIdInfo()
              .then(this.handleReadSuccess)
              .catch(this.handleError)
          } else if (this.deviceName === 'hs') {
            readcard().then(res => {
              if (res.data.resultFlag === 0) {
                this.$message.success('读取成功！')
                this.tempValue = res.data.certNumber
                this.$emit('input', res.data.certNumber)
                this.$emit('change', { Name: res.data.partyName, IDNumber: res.data.certNumber })

                closeDevice()
                this.active = false
                this.loading = false
              } else if (res.data.resultFlag === -11) {
                this.retry(1000)
              }
            }).catch(this.handleError)
          } else if (this.deviceName === 'xzx') {
            this.loading = true
            this.active = true
            readcard_xzx().then(res => {
              if (res.data.retcode === '0x1') {
                this.$message.error(res.data.retmsg)
                this.loading = false
                this.active = false
                return ''
              } else if (res.data.retcode === '0x41') {
                this.retry(1000)
              } else if (res.data.retcode === '0x90 0x1') {
                this.tempValue = res.data.cardno
                this.$emit('input', res.data.cardno)
                this.$emit('change', { Name: res.data.name, IDNumber: res.data.cardno })
                this.active = false
                this.loading = false
              }
            })
          } else if (this.deviceName === 'jl') {
            getReadCert().then(res => {
              if (res.resultFlag === 0) {
                this.$message.success('读取成功！')
                this.tempValue = res.resultContent.certNumber
                this.$emit('input', res.resultContent.certNumber)
                this.$emit('change', { Name: res.resultContent.partyName, IDNumber: res.resultContent.certNumber })
                getReaderDisconnect()
                this.active = false
                this.loading = false
              } else if (res.resultFlag === -1) {
                this.retry(1000)
              }
            }).catch(this.handleError)
          }

          break
        case 'IC':
          getIccard(this.comName[3], this.isPay)
            .then(this.handleReadSuccess)
            .catch(this.handleError)
          break
      }
    },
    handleReadSuccess (data) {
      console.log(data)
      switch (data.ret) {
        case 0:
          if (this.type === 'IC') {
            if (this.isPay) {
              if (data.data.ICdata) {
                this.$message.success('读取成功！')
                this.tempValue = data.data.ICdata.replace(/F/g, '')

                this.$emit('input', this.tempValue)
                this.$emit('change', this.tempValue)
              } else {
                this.$message.error('卡号获取失败')

                this.retry(1000)
              }

              return
            }
            this.$message.success('读取成功！')
            this.tempValue = data.data.ICSnr
            // this.tempValue = '123'

            // IC卡位数补全
            const val = this.$localStore.get('ICCardLength') === 0 ? this.tempValue : this.tempValue.padStart(this.$localStore.get('ICCardLength') || 10, '0')

            this.$emit('input', val)
            this.$emit('change', val)
            this.loading = false
          } else {
            this.$message.success('读取成功！')
            this.tempValue = data.Certificate.IDNumber
            if (data.Certificate.oldIDnum) {
              this.tempValue = data.Certificate.oldIDnum
            }
            if (data.Certificate.EnName) {
              data.Certificate.Name = data.Certificate.EnName
            }
            this.$emit('input', this.tempValue)
            this.$emit('change', data.Certificate)
            this.loading = false
          }

          break
        case 1:
          this.$message.error('未连接读卡器，请检查设备后重试。')
          this.loading = false
          break
        case 201:
        case 11:
          this.retry(1000)
          return
      }
      this.active = false
    },
    retry (time) {
      if (this.finished) return
      this.timer = setTimeout(() => {
        this.getDevice()
      }, time || 2000)
    },
    // 东信社保卡
    getDonseeSBK () {
      this.$store.dispatch('readSocialCard', this._uid)
    },
    handleError (e) {
      e && console.log(e)
      this.$message.error('未连接读卡器，请检查设备后重试。')
      this.active = false
      this.loading = false
    }
  },
  watch: {
    value: {
      handler (val) {
        this.tempValue = val
      },
      immediate: true
    },
    donseeMessage: {
      handler (msg) {
        console.log('%c [ this.messageUid ]-383', 'font-size:13px; background:pink; color:#bf2c9f;', this.messageUid)
        console.log('%c [ this._uid ]-384', 'font-size:13px; background:pink; color:#bf2c9f;', this._uid)
        if (this.messageUid !== this._uid) return

        switch (msg.fun) {
          case 'EST_Reader_ReadIDCard#':
            this.$emit('input', msg.certNo)
            this.$emit('change', { Name: msg.name, IDNumber: msg.certNo })
            break
          case 'EST_ReadSocialCard#':
            this.$emit('input', msg.SHBZHM)
            this.$emit('change', { Name: msg.XM, IDNumber: msg.SHBZHM })
            break
          case 'EST_ReadM1Card#':
            this.$emit('input', this.padString(parseInt(msg.UID, 16) + ''))
            break
          default:
            break
        }
      },
      deep: true
    }
  },
  computed: {
    // 东信EST-100R 设备消息
    donseeMessage () {
      return this.$store.state.donsee100R.message
    },
    messageUid () {
      return this.$store.state.donsee100R.uid
    },
    scenicName () {
      return this.$store.state.user.scenicName
    },
    age () {
      const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
      if (reg.test(this.tempValue)) {
        let nowYear = new Date().getFullYear()
        let birthYear = this.tempValue.substring(6, 10)
        return (nowYear - birthYear)
      } else {
        return '-'
      }
    }

  },
  beforeDestroy () {
    if (this.active) {
      this.startRead()
    }

    this.cardSearchTimer && clearTimeout(this.cardSearchTimer)

    this.hsWsApi && this.hsWsApi.closeConnect()
  }
}
</script>

<style lang="scss" scoped>
.readerInput,.readerInput2 {
  ::v-deep .el-input__clear {
    position: relative;  z-index: 10;
  }
}
.readerInput {
  ::v-deep .el-input__inner{
    padding-right: 80px;
  }
}
.readCard {
  position: absolute;  display: flex; height: 100%; font-size: 12px; color: #fff; cursor: pointer;align-items: center;  z-index: 0;
  .inner {
    display: flex; height: 80%; padding: 0 5px;   border-radius: 5px; align-items: center;margin-right: 5px;white-space: nowrap; flex:1;
  }

  .wave {
    position: absolute;top: 50%; left: 50%;display: none; width: 20px;height: 20px;box-sizing: border-box;margin-top: -10px;margin-left: -10px; background: rgba(255, 255, 255, .384); border: 1px solid red; border-radius: 50%; opacity: 0; animation: wave infinite linear 1s forwards;
  }
  .wave2 {
    opacity: 0;  animation: wave infinite 2s 1s forwards;
  }
  .svg-icon {
    position: relative;  width: 16px; height: 16px; margin-right: 5px;font-size: 16px;
  }
  &.active {
    .wave {
      display: block;
    }
    .svg-icon {
      color: #fff;
    }
  }
}

@keyframes wave {
  0% {
    opacity: 0; transform: scale(3);
  }
  50% {
    opacity: .5; transform: scale(1);
  }
  100% {
    opacity: 0; transform: scale(0);
  }
}
</style>
