<template>
  <div class="form-group micro-qrcode">
    <label :for="`inputQrCaption${_uid}`" v-if="caption">{{ caption }}</label>

    <div v-if="! scanning" @click="toggleScanning">
      <slot name="startScan">
        <a href="javascript:;" class="btn btn-primary btn-block">
          <span class="mdi mdi-qrcode-scan"></span> 
          Start QR scan
        </a>
      </slot>
    </div>
    <div v-else @click="toggleScanning">
      <slot name="stopScan">
        <a href="javascript:;" class="btn btn-danger btn-block">
          <span class="mdi mdi-qrcode-scan"></span>
          Stop QR scan
        </a>
      </slot>
    </div>

    <canvas :id="`inputQrCanvas${_uid}`" hidden></canvas>
    <video v-show="scanning" :id="`inputQrVideo${_uid}`" class="mt-3 mb-3"></video>

    <table class="table" v-if="showResults" v-show="scanResults.length">
      <thead>
        <tr>
          <th scope="col">Value</th>
          <th scope="col">Scanned</th>
          <th scope="col">&nbsp;</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item, index) in scanResults" :key="`bc-${item.value}`">
          <td>{{ item.value }}</td>
          <td>{{ item._created | readable_time }}</td>
          <td class="text-right"><a href="javascript:;" class="text-danger" @click="scanResults.splice(index, 1) && $emit('input', scanResults)"><span class="mdi mdi-delete"></span></a></td>
        </tr>
      </tbody>
    </table>

    <small class="form-text text-muted">
      {{ description }}
    </small>
  </div>
</template>

<script>
  import jsQR from 'jsqr'
  import readableTime from 'readable-timestamp'

  export default {
    props: {
      caption: String, 
      value: [ Object, Array],
      description: String, 
      field: Object, 
      continueAfterResult: Boolean, 
      autoStart: Boolean,
      showResults: {
        type: Boolean,
        default: true,
      },
    },

    data() {
      return {
        hasCamera: false,
        scanner: null,
        video: null,
        canvasElement: null,
        scanning: false,
        scanResults: [],
      }
    },

    filters: {
      readable_time: function (value) {
        var d = new Date(value)
        return readableTime(d)
      },
    },

    mounted () {
      const vm = this

      vm.video = document.getElementById(`inputQrVideo${vm._uid}`)
      vm.canvasElement = document.getElementById(`inputQrCanvas${vm._uid}`)

      if (vm.autoStart) {
        vm.toggleScanning()
      }
    },

    beforeDestroy () {
      const vm = this

      vm.video.pause()

      if (vm.video && vm.video.srcObject && vm.video.srcObject.getTracks()) {
        vm.video.srcObject.getTracks().forEach(track => track.stop());
        vm.video.removeAttribute('src')
        vm.video.load()
      }

      if (vm.scanner) {
        // vm.scanner.destroy()
      }
    },

    methods: {
      drawLine(begin, end, color) {
        const vm = this

        let canvas = vm.canvasElement.getContext("2d")

        canvas.beginPath();
        canvas.moveTo(begin.x, begin.y);
        canvas.lineTo(end.x, end.y);
        canvas.lineWidth = 4;
        canvas.strokeStyle = color;
        canvas.stroke();
      },

      tick () {
        const vm = this

        if (vm.video.readyState === vm.video.HAVE_ENOUGH_DATA) {
          vm.canvasElement.height = vm.video.videoHeight;
          vm.canvasElement.width = vm.video.videoWidth;

          let canvas = vm.canvasElement.getContext("2d")
          canvas.drawImage(vm.video, 0, 0, vm.canvasElement.width, vm.canvasElement.height);
          let imageData = canvas.getImageData(0, 0, vm.canvasElement.width, vm.canvasElement.height);
          let code = jsQR(imageData.data, imageData.width, imageData.height, {
            inversionAttempts: "dontInvert",
          });

          if (code) {
            // vm.drawLine(code.location.topLeftCorner, code.location.topRightCorner, "#FF3B58");
            // vm.drawLine(code.location.topRightCorner, code.location.bottomRightCorner, "#FF3B58");
            // vm.drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner, "#FF3B58");
            // vm.drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner, "#FF3B58");
            let result = code.data

            let result_exists = false

            vm.scanResults.forEach(res => {
              if (res.value == result) {
                result_exists = true
                return false
              }
            })

            if (! result_exists) {
              vm.scanResults.push({
                value: result,
                _created: new Date().getTime(),
              })

              vm.$emit('input', vm.scanResults)
            }

            if (! vm.continueAfterResult) {
              vm.toggleScanning()
            }

          } else {
          }
        }

        requestAnimationFrame(vm.tick)
      },

      toggleScanning () {
        const vm = this

        if (vm.scanning) {
          // console.log('Pause')
          vm.video.pause()

          vm.video.srcObject.getTracks().forEach(track => track.stop());
          vm.video.removeAttribute('src')
          vm.video.load()
        } else {
          // console.log('Start')
          navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } }).then(function(stream) {
            vm.video.srcObject = stream;
            vm.video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
            vm.video.play()
            requestAnimationFrame(vm.tick);
          })
        }

        vm.scanning = ! vm.scanning
      },

      handleInput(e) {
        this.$emit('input', e.target.value)
      },
    }
  }
</script>

<style lang="scss">
.micro-qrcode {
  video {
    width: 100%;
    height: 180px;
  }
}
</style>