<template>
  <el-dialog
    :visible.sync="visible"
    :before-close="handleClose"
    :title="`游客信息 ( ${message} )`"
    width="1300px">
    <div class="guestInfo-dialog">
      <div class="btn-wrap-left">
        <div style="display:flex">
          <el-button
            plain
            size="mini"
            type="primary"
            @click="handleAdd"
          >
            添加游客
          </el-button>
          <el-button
            v-if="deviceName==='donsee-100R'"
            size="mini"
            type="primary"
            @click="getDonseeSBK"
          >
            读取社保卡
          </el-button>
          <el-button
            v-else-if="deviceName!=='tecsun'"
            size="mini"
            type="primary"
            @click="$refs.SSCQrCodeReader.show()"
          >
            读取社保卡
          </el-button>

          <div style="flex:1">
            <div
              v-if="projectName==='jiulonghu'"
              style="padding:10px;display: flex;">
              <span style="flex:1"> 全价: {{ touristData.length-age1-age3-age4 }} 人</span>
              <span style="flex:1"> 半价: {{ age1+age3 }} 人</span>
              <span style="flex:1"> 免票: {{ age4 }} 人</span>
              <span style="flex:1"> </span>
            </div>
          </div>

          <el-button
            v-if="checkTicketNo&&touristData[0]"
            :disabled="!touristData[0].ticketNo"
            @click="getTicketNos"
          >
            查询预印票
          </el-button>

          <el-button
            plain
            size="mini"
            type="primary"
            @click="downloadTemp"
            style="margin-right:10px"
            v-if="showUpload"
          >
            下载模板
          </el-button>

          <el-upload
            :action="uploadUrl"
            :headers="requestHeader"
            :auto-upload="true"
            :show-file-list="false"
            :on-success="handleSuccess"
            :on-error="handleError"
            v-if="showUpload"
          >
            <el-button
              size="mini"
              type="primary"
            >
              导入模板
            </el-button>
          </el-upload>
        </div>
      </div>

      <el-form
        class="table-box"
        ref="form"
        :model="model"
      >
        <el-table
          border
          stripe
          class="guest-info-table"
          :data="model.touristList.slice((currentPage - 1) * pageSize,currentPage * pageSize)"
        >
          <el-table-column
            label="#"
            type="index"
            width="50"
          >
          </el-table-column>

          <el-table-column
            prop="guestName"
            label="游客姓名"
          >
            <template slot-scope="scope">
              <el-form-item
                verify
                can-be-empty
                :prop="'touristList.' + scope.$index + '.guestName'"
              >
                <el-input
                  clearable
                  size="small"
                  :disabled="scope.row.lock"
                  v-model="scope.row.guestName"
                ></el-input>
              </el-form-item>
            </template>
          </el-table-column>
          <el-table-column
            prop="guestPhone"
            label="游客手机号"
          >
            <template slot-scope="scope">
              <el-form-item
                verify
                can-be-empty
                :prop="'touristList.' + scope.$index + '.guestPhone'"
              >
                <el-input
                  clearable
                  size="small"
                  :disabled="scope.row.lock"
                  v-model="scope.row.guestPhone"
                ></el-input>
              </el-form-item>
            </template>
          </el-table-column>
          <el-table-column
            prop="guestIdentifyType"
            label="证件类型"
          >
            <template slot-scope="scope">
              <el-form-item
                verify
                can-be-empty
                :prop="'touristList.' + scope.$index + '.guestIdentifyType'"
              >
                <el-select
                  value-key="id"
                  v-model="scope.row.guestIdentifyType"
                  placeholder="请选择">
                  <el-option
                    v-for="(item, idx) in papersOption"
                    :key="`id-${idx}`"
                    :label="item.label"
                    :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
            </template>
          </el-table-column>
          <el-table-column
            label="证件号码"
            min-width="120"
          >
            <template slot-scope="scope">
              <el-form-item
                can-be-empty
                :verify="validateList[scope.row.guestIdentifyType]"
                :prop="'touristList.' + scope.$index + '.guestIdentify'"
              >
                <el-input
                  clearable
                  size="small"
                  class="id"
                  :disabled="scope.row.lock"
                  v-model="scope.row.guestIdentify"
                  @blur="getAge()"
                ></el-input>
              </el-form-item>
            </template>
          </el-table-column>

          <el-table-column
            label="IC卡号码"
            min-width="120"
          >
            <template slot-scope="scope">
              <el-form-item
                can-be-empty
                :prop="'touristList.' + scope.$index + '.cardNo'"
              >
                <ReaderInput
                  type="ID"
                  @change="scope.row.cardNo=$event.Name"
                  v-model="scope.row.cardNo"></ReaderInput>
              </el-form-item>
            </template>
          </el-table-column>

          <el-table-column
            label="票号"
            min-width="160"
            v-if="checkTicketNo"
          >
            <template slot-scope="scope">
              <el-form-item
                :prop="'touristList.' + scope.$index + '.ticketNo'"
              >
                <QRReader v-model="scope.row.ticketNo"></QRReader>
              </el-form-item>
            </template>
          </el-table-column>

          <el-table-column
            label="人脸照片"
            min-width="130"
          >
            <template slot-scope="scope">
              <div class="faceWrap">
                <GetFace v-model="scope.row.face"></GetFace>
              </div>
            </template>
          </el-table-column>

          <el-table-column
            label="操作"
          >
            <template slot-scope="scope">
              <span
                v-if="touristData.length>1"
                class="el-button el-button--primary el-button--mini"
                @click="handleDelete(scope.row.idKey)"
              >
                <i class="el-icon-delete"></i>
                删除
              </span>
            </template>
          </el-table-column>
        </el-table>
        <el-pagination
          background
          layout="sizes,prev, pager, next, slot"
          :total="model.touristList.length"
          :page-size="pageSize"
          @current-change="currentChange"
          @size-change="handleSizeChange"
          :page-sizes="[5,10,15,20]"
          :current-page="currentPage"
        >
          <span style="float: right;">
            共计：{{ touristData.length }} 人
          </span>
        </el-pagination>
      </el-form>

      <div class="dialog-btn-wrap">
        <el-button
          @click="handleClose">
          取消
        </el-button>
        <el-button
          type="primary"
          @click="handleSave">
          确定
        </el-button>
      </div>
    </div>
    <SSCQrCodeReader
      ref="SSCQrCodeReader"
      @getSSCList="getSSCList"></SSCQrCodeReader>
  </el-dialog>
</template>

<script>
import getTecsun from '@/api/dsReaderApi' // 德生社保卡读卡器
import { setTourist } from '@/pages/common'
import { verifyId, verifyPhone, verifyId_HUZHAO, verifyId_GANGAO, verifyId_TAIBAO } from '@/utils/validate'
import { getIdInfo } from '@/api/ZTKReaderApi'
import { getReadCert } from '@/api/JinlunReaderApi'
import HuashiReaderWsApi from '@/api/HuashiReaderWsApi'
import donsee from '@/api/donsee'
import { IDENTIFY_TYPES } from '@/const'
import GetFace from '@/components/GetFace'
import { openDevice, readcard, closeDevice } from '@/api/HuashiReaderApi'
import { readcard_xzx } from '@/api/xzxReaderApi'
import { randomString } from '@/utils'
import { debounce } from 'throttle-debounce'
import { getTicketInStockByQrcodeAndNumber } from '@/api/ticketType'
import { getAgeByCardId } from '@/utils/index.js'
import { getToken } from '@/utils/auth'

export default {
  props: {
    // 是否需要填写游客信息
    checkId: {
      type: Boolean,
      default: false
    },
    // 是否需要填写人脸信息
    checkFace: {
      type: Boolean,
      default: false
    },
    // 是否需要填写票号
    checkTicketNo: {
      type: Boolean,
      default: false
    },
    checkIc: {
      type: Boolean,
      default: false
    },
    touristList: {
      type: Array,
      default: () => []
    },
    // 不同组件，游客数据不同，把游客数据更新交给父组件的方法来处理
    updateTourist: {
      type: Function,
      default: () => {}
    }
  },
  components: {
    GetFace
  },
  computed: {
    model () {
      return { touristList: this.touristData }
    },
    // 东信EST-100R 设备消息
    donseeMessage () {
      return this.$store.state.donsee100R.message
    },
    messageUid () {
      return this.$store.state.donsee100R.uid
    },
    validateInfo () {
      const { checkId, checkFace, checkTicketNo, checkIc } = this

      return [
        {
          key: 'guestIdentify',
          validate: checkId,
          message: '证件号码'
        },
        {
          key: 'face',
          validate: checkFace,
          message: '人脸照片'
        },
        {
          key: 'ticketNo',
          validate: checkTicketNo,
          message: '票号'
        },
        {
          key: 'cardNo',
          validate: checkIc,
          message: 'IC卡号码'
        }
      ]
    },
    requestHeader () {
      return {
        SaToken: getToken()
      }
    }
  },
  data () {
    return {
      projectName: process.env.VUE_APP_PROJECT,
      age1: 0, // 0-18
      age2: 0, // 19-59
      age3: 0, // 60-69
      age4: 0, // 70-
      message: '请刷卡读取身份证信息',
      visible: false,
      touristData: [],
      deviceName: this.$localStore.get('idDevice'),
      pageSize: 5,
      currentPage: 1,
      validateList: {
        '0': verifyId,
        'HUZHAO': verifyId_HUZHAO,
        'GANGAO': verifyId_GANGAO,
        'TAIBAO': verifyId_TAIBAO
      },
      papersOption: IDENTIFY_TYPES,
      uploadUrl: '',
      showUpload: true,
      hsWsApi: null
    }
  },
  methods: {
    verifyId,
    verifyPhone,
    show () {
      this.currentPage = 1
      this.visible = true
      this.$nextTick(() => {
        // 编辑状态不更新到真实的游客列表
        this.touristData = JSON.parse(JSON.stringify(this.touristList))
        this.startReadCard()
        this.getAge()
      })

      if (this.deviceName === 'hs-ws') {
        this.hsWsApi = new HuashiReaderWsApi()
      }
    },

    // 获取社保卡信息
    getSSCList (info) {
      setTourist(this.touristData, 1, { Name: info.name, IDNumber: info.idNum })
    },
    currentChange (e) {
      this.currentPage = e
    },
    handleSizeChange (val) {
      console.log(val)
      this.pageSize = val
    },
    startReadCard () {
      // 身份证读卡
      this.timer && clearTimeout(this.timer)
      this.finished = false
      this.getIdInfo()
    },
    // 东信社保卡
    getDonseeSBK () {
      this.$store.dispatch('readSocialCard', this._uid)
    },
    handleDonsee100R () {
      // 连续读取身份证信息
      this.$store.dispatch('readIDCard', this._uid)

      this.cardSearchTimer = setTimeout(() => {
        this.handleDonsee100R()
      }, 1000)
    },
    async getIdInfo () {
      if (this.finished) return
      if (this.deviceName === 'donsee-100R') {
        return this.handleDonsee100R()
      }

      let data
      try {
        switch (this.deviceName) {
          // 德生社保卡读卡器
          case 'tecsun':
            data = await getTecsun(this)
            if (data) {
              setTourist(this.touristData, 1, { guestName: data.name, IDNumber: data.idNum })
            }
            break
          case 'zk':
            data = await getIdInfo()
            // 更新身份证信息
            if (data.Certificate) {
              setTourist(this.touristData, 1, data.Certificate)
            }
            break
          case 'hs':
            await closeDevice()

            await openDevice().then(res => {
              if (res.data.resultFlag === 0) {
                readcard().then(res => {
                  if (res.data.resultFlag === 0) {
                    setTourist(this.touristData, 1, { guestName: res.data.partyName, IDNumber: res.data.certNumber })

                    closeDevice()
                  }
                })
              } else {
                this.message = '身份证读卡器暂时无法使用，请检查；关闭弹窗后重试'
              }
            }).catch(e => {
              this.message = '身份证读卡器暂时无法使用，请检查；关闭弹窗后重试'
            })
            break
          case 'hs-ws':
            if (!this.hsWsApi) return
            if (this.hsWsApi.isConnected) {
              this.hsWsApi.addMessageListener((res) => {
                if (res.data === 'failed to obtain ID card information') {
                  this.message = '读取失败，请重试'
                  this.getIdInfo()
                  return
                }

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

                if (alldata.length >= 17) {
                  setTourist(this.touristData, 1, { Name: alldata[3], IDNumber: alldata[8] })
                  this.hsWsApi.closeConnect()
                }
              })

              this.hsWsApi.readIDCard(1500)
            } else {
              this.hsWsApi.closeConnect()
              this.hsWsApi.connect((isConnected) => {
                if (isConnected) {
                  this.message = '身份证读卡器已连接'
                  // this.timer && clearTimeout(this.timer)
                } else {
                  this.message = '身份证读卡器暂时无法使用，请检查；关闭弹窗后重试'
                }
              })
            }

            break
          case 'xzx':
            readcard_xzx().then(res => {
              if (res.data.retcode === '0x1') {
                this.message = '身份证读卡器暂时无法使用，请检查；关闭弹窗后重试'
              } else if (res.data.retcode === '0x90 0x1') {
                setTourist(this.touristData, 1, { Name: res.data.name, IDNumber: res.data.cardno })
              }
            })
            break
          case 'jl':
            data = await getReadCert()
            // 更新身份证信息
            if (data.resultContent) {
              setTourist(this.touristData, 1, { Name: data.resultContent.partyName, IDNumber: data.resultContent.certNumber })
            }
            break
          case 'donsee':
            const dev = donsee()
            if (!dev) return
            const info = dev.readSfz() || dev.readSiCard()

            if (info) {
              setTourist(this.touristData, 1, { Name: info.pName, IDNumber: info.pCertNo })
            }

            break
        }

        this.timer = setTimeout(() => {
          this.getIdInfo()
        }, 500)
      } catch (e) {
        console.log(e)
        this.message = '身份证读卡器暂时无法使用，请检查；关闭弹窗后重试'
        // this.$message.warning('读卡器连接出现了问题，请关闭弹窗后重试')
      }
    },
    handleAdd () {
      setTourist(this.touristData, 1)
      this.getAge()
    },
    handleDelete (idKey) {
      let index = this.touristData.findIndex(item => {
        return item.idKey === idKey
      })
      this.touristData.splice(index, 1)
      this.getAge()
    },
    resetForm () {
      this.$refs.form.resetFields()
    },
    handleClose () {
      this.visible = false
      this.message = '请刷卡读取身份证信息'
      this.finished = true
      this.resetForm()

      this.timer && clearTimeout(this.timer)

      this.cardSearchTimer && clearTimeout(this.cardSearchTimer)

      if (this.deviceName === 'donsee-100R') {
        this.$store.dispatch('stopAutoReadIDCard')
      }

      this.hsWsApi && this.hsWsApi.closeConnect()
    },
    validateTourist () {
      // 验证游客信息
      let validateMsg = []
      this.validateInfo.forEach(item => {
        if (item.validate) {
          this.touristData.forEach(v => {
            if (!v[item.key]) {
              validateMsg.push(item.message)
            }
          })
        }
      })
      return validateMsg
    },
    handleSave: debounce(1000, true, function () {
      const validateMsg = this.validateTourist()

      if (validateMsg.length > 0) {
        this.$message.error(`请填写游客信息：${validateMsg.join('、')}${validateMsg.length > 1 ? '等' : ''}`)
        return
      }
      // if (this.checkId) {
      //   // 是否存在未填写的内容
      //   let blankData = this.touristData.find(item => {
      //     return !item.guestName || !item.guestIdentify
      //   })

      //   if (blankData) {
      //     this.$message.error('证件入园，证件信息不完整，请检查')
      //     return
      //   }
      // }

      // if (this.checkFace) {
      //   // 是否存在未填写的内容
      //   let blankData = this.touristData.find(item => {
      //     return !item.face
      //   })

      //   if (blankData) {
      //     this.$message.error('人脸入园，游客人脸信息不完整，请检查')
      //     return
      //   }
      // }

      // if (this.checkTicketNo) {
      //   // 是否存在未填写的内容
      //   let blankData = this.touristData.find(item => {
      //     return !item.ticketNo
      //   })

      //   if (blankData) {
      //     this.$message.error('预印票，票号信息不完整，请检查')
      //     return
      //   }
      // }

      this.$refs.form.validate().then(val => {
        if (val) {
          console.log(val)
          // 表单重置时，会导致当前对象被清空。避免操作了错误的对象
          let newData = JSON.parse(JSON.stringify(this.touristData))
          this.updateTourist(newData)
          this.handleClose()
        }
      }).catch(e => {
        this.$message.error('输入的信息有误，请检查')
      })
    }),
    downloadTemp () {
      window.location.href = require('path').join(__static, '游客信息导入模板.xlsx')
    },
    handleSuccess (response, file, fileList) {
      if (response.code === '200') {
        this.$message.success('上传成功')
        setTourist(this.touristData, -this.touristData.length) // 清空现有数组
        setTourist(this.touristData, response.data.length) // 预先构建导入数组
        this.touristData.forEach((v, i) => { // 填充导入数据
          v.guestName = response.data[i].guestName
          v.guestIdentify = response.data[i].guestIdentify
          v.guestIdentifyType = this.papersOption.find(v => v.label === response.data[i].guestIdentifyType).id
          v.idKey = randomString()
        })
      } else {
        this.$message.error('上传失败')
      }
    },
    handleError (e) {
      this.$message.error('上传失败')
    },
    getAge () {
      if (this.projectName !== 'jiulonghu') return
      this.age1 = 0
      this.age2 = 0
      this.age3 = 0
      this.age4 = 0
      this.touristData.forEach(v => {
        let age
        if (v.guestIdentifyType === 0 && v.guestIdentify.length === 18) {
          age = getAgeByCardId(v.guestIdentify)
          if (age < 18) { // 半价
            this.age1++
          } else if (age > 59 && age < 70) { // 半价
            this.age3++
          } else if (age > 70) { // 免费
            this.age4++
          } else {
            this.age2++
          }
        }
      })
    },
    async getTicketNos () {
      const { data } = await getTicketInStockByQrcodeAndNumber({ keyWords1: this.touristData[0].ticketNo, keyWords2: this.model.touristList.length })
      this.touristData.forEach((v, i) => {
        this.$set(v, 'ticketNo', data[i])
      })
    }
  },
  watch: {
    donseeMessage: {
      handler (msg) {
        console.log('%c [ this.messageUid ]-518', 'font-size:13px; background:pink; color:#bf2c9f;', this.messageUid)
        console.log('%c [ this._uid ]-519', 'font-size:13px; background:pink; color:#bf2c9f;', this._uid)
        if (this.messageUid !== this._uid) return

        switch (msg.fun) {
          case 'EST_Reader_ReadIDCard#':
            setTourist(this.touristData, 1, { Name: msg.name, IDNumber: msg.certNo })
            break
          case 'EST_ReadSocialCard#':
            setTourist(this.touristData, 1, { Name: msg.XM, IDNumber: msg.SHBZHM })
            break
          default:
            break
        }
      },
      deep: true
    }
  },
  created () {
    const Store = require('electron-store')
    const localStore = new Store()
    this.uploadUrl = localStore.get('serverUrl') + 'admin/util/importGuest'
    // this.showUpload = (this.$route.name === 'group' || this.$route.name === 'retail')
    // 20230506 除了团体售票(group)，散客售票(retail)现在也需要显示“下载模板”和“导入模板”
  },
  beforeDestroy () {
    this.timer && clearTimeout(this.timer)

    this.cardSearchTimer && clearTimeout(this.cardSearchTimer)

    if (this.deviceName === 'donsee-100R') {
      this.$store.dispatch('stopAutoReadIDCard')
    }

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

<style lang="scss" scoped>
.faceWrap{
  width: 200px;
  .getFace{
    display: flex; align-items: center;
  }
}
</style>
