<template>
  <el-dialog
    destroy-on-close
    append-to-body
    title="扫码二维码"
    :visible.sync="visible"
    width="30%"
    @close="handleClose">
    <div class="box">
      <video
        :id="videoID"
        preload
        autoplay
        loop
        muted></video>
      <canvas
        :id="videoCanvasID"
        ref="videoCanvas"
        hidden></canvas>
      <canvas
        :id="canvasID"
        ref="canvas"
        hidden></canvas>
    </div>
    <span slot="footer">
      <span v-if="this.countdown > -1">票号：{{ codeNo }} ({{ this.countdown }}s) </span> <el-button @click="visible = false">取 消</el-button>
    </span>
  </el-dialog>
</template>

<script>
import jsQR from 'jsqr'
import { checkTickets } from '@/api/order'

export default {
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      videoID: `video${this._uid}`,
      canvasID: `canvas${this._uid}`,
      videoCanvasID: `videoCanvasID${this._uid}`,
      visible: false,
      running: true,
      scanSuccess: false,
      type: '',
      countdown: -1, // 检票倒计时
      codeNo: ''
    }
  },
  methods: {
    show (type) {
      this.type = type
      this.running = true
      this.visible = true

      this.$nextTick(() => {
        this.start()
      })
    },
    drawLine (begin, end, color) {
      this.canvas.beginPath()
      this.canvas.moveTo(begin.x, begin.y)
      this.canvas.lineTo(end.x, end.y)
      this.canvas.lineWidth = 4
      this.canvas.strokeStyle = color
      this.canvas.stroke()
    },
    start () {
      this.canvasEl = document.getElementById(this.canvasID)
      this.video = document.getElementById(this.videoID)
      this.canvas = this.canvasEl.getContext('2d')
      this.videoCanvasEl = document.getElementById(this.videoCanvasID)
      this.videoCanvas = this.videoCanvasEl.getContext('2d')

      navigator.mediaDevices.getUserMedia({
        video: {
          facingMode: 'environment'
        }
      }).then((stream) => {
        this.video.srcObject = stream
        this.video.setAttribute('playsinline', true) // required to tell iOS safari we don't want fullscreen
        this.video.play()
        this.timer = requestAnimationFrame(this.tick)

        // 如果窗口已关闭，则关闭摄像头
        if (!this.visible) {
          this.video.srcObject && this.video.srcObject.getVideoTracks().forEach(t => {
            t.stop()
          })
        }
      }).catch(e => {
        this.$message.error('摄像头打开失败，请检查设备')
      })
    },
    tick () {
      if (!this.visible) {
        return false
      }
      this.msg = '⌛ Loading video...'
      if (this.video.readyState === this.video.HAVE_ENOUGH_DATA) {
        this.msg = ''
        this.canvasEl.hidden = false
        this.canvasEl.height = this.video.videoHeight
        this.canvasEl.width = this.video.videoWidth
        this.videoCanvasEl.height = this.video.videoHeight
        this.videoCanvasEl.width = this.video.videoWidth
        this.videoCanvas.drawImage(this.video, 0, 0, this.canvasEl.width, this.canvasEl.height)
        var imageData = this.videoCanvas.getImageData(0, 0, this.videoCanvasEl.width, this.videoCanvasEl.height)
        var code = jsQR(imageData.data, imageData.width, imageData.height, {
          inversionAttempts: 'dontInvert'
        })

        if (code && !this.getSuccess) {
          this.drawLine(code.location.topLeftCorner, code.location.topRightCorner, '#FF3B58')
          this.drawLine(code.location.topRightCorner, code.location.bottomRightCorner, '#FF3B58')
          this.drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner, '#FF3B58')
          this.drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner, '#FF3B58')

          if (!this.scanSuccess && code.data) {
            this.scanSuccess = true
            this.running = false
            if (this.type === 'fastCheck') {
              console.log('code.data', code.data)
              checkTickets({ list: [code.data] }).then(res => {
                this.$message.success('检票成功')
                this.codeNo = code.data
                this.scanTimer(true, 2, 2000)
              }).catch(() => {
                this.codeNo = code.data
                this.scanTimer(false, 1, 1000)
              })
            } else {
              this.$emit('input', code.data)
              this.handleClose()
            }
          }
        }
      }
      if (this.running) requestAnimationFrame(this.tick)
    },
    // 扫码计时
    scanTimer (update, countdown, time) {
      this.countdown = countdown
      let timer = setInterval(() => {
        if (this.countdown > -1) {
          --this.countdown
        } else {
          clearInterval(timer)
        }
      }, 1000)
      setTimeout(() => {
        if (this.visible === true) {
          this.running = true
          this.scanSuccess = false
          this.tick()
        }
        update && this.$emit('updateList')
      }, time)
    },
    handleClose () {
      this.visible = false
      this.scanSuccess = false

      this.timer && clearInterval(this.timer)
      this.video.srcObject && this.video.srcObject.getVideoTracks().forEach(t => {
        t.stop()
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.box{
    width: 100%; padding-bottom: 90%; background: rgba(0, 0, 0, 0.384); position: relative; overflow: hidden;
}
video,
canvas {
  position: absolute;  top: 0;  left: 0;  object-fit: cover;width: 100%;  height: 100%;transform: rotateY(180deg)
}
</style>
