<template>
  <div>
    <div class="q-ma-md" v-if="askForPermission">

      <q-btn @click="toggleCamera(!activateCamera)" :loading="loading" unelevated color="positive" stack
             icon="photo_camera"
      label="QR-Code scannen" class="full-width q-mt-sm"/>
      <p class="q-mt-sm"><b>Hinweis:</b> Um den QR-Code scannen zu können, müssen Sie den Zugriff auf Ihre Kamera erlauben.</p>
    </div>
    <div v-if="activateCamera">
      <qrcode-drop-zone @decode="onDecode" @init="logErrors">
        <qrcode-stream :paused="paused" @decode="onDecode" @init="onInit">
          <div v-if="validating" >
            <div class="light-dimmed fit">
            </div>
            <q-spinner-oval
              class="absolute-center"
              color="primary"
              size="10em"
            />
          </div>
        </qrcode-stream>
      </qrcode-drop-zone>
      <div class="q-ma-md">
        <q-btn v-if="!askForPermission" @click="toggleCamera(!activateCamera)" :loading="loading" unelevated color="primary" stack
               label="Schließen" class="full-width"/>
      </div>
    </div>
    <qrcode-capture v-if="noStreamApiSupport" @decode="onDecode"/>
  </div>
</template>

<script>
  export default {
    name: 'qrscanner',
    data() {
      return {
        askForPermission: true,
        activateCamera: false,
        isValid: false,
        validating: false,
        loading: false,
        paused: false,
        result: null,
        params: null,
        noStreamApiSupport: false,

        cacheID: null,
      }
    },
    created() {
      this.setCacheId();
    },
    methods: {
      setCacheId() {
        console.log("qr-code: 'cache' from url: " + this.$route.params.cache);
        this.cacheID = this.$route.params.cache ? this.$route.params.cache : null;
      },

      async onDecode(content) {
        this.result = content;

        this.pauseCamera();

        this.validating = true;
        this.isValid = await this.validate();

        window.setTimeout(() => {
          this.validating = false;
          this.unPauseCamera();
        }, 2000)
        //this.unPauseCamera();
      },

      validate() {
        return new Promise(resolve => {
          let params = this.setParams();
          console.log(params);
          if (!params.cacheID || !params.stationID || !params.durchgefuehrterCacheID || !params.token) {
            console.log("Parameter konnten nicht erkannt werden.");
            resolve(false);
            console.log("Parameter konnten nicht erkannt werden.");
          } else {
            this.$axios.put('/api/checkStation', null, { params })
              .then((response) => {
                console.log("resolve(true)");
                console.log("cache access definition");
                console.log(response.data.cacheAccesDefinition);
                resolve(true);
                if (Number(response.data.cacheAccesDefinition.id) === 0) {
                  this.$router.push({path: `/station/${params.cacheID}/${params.stationID}`});
                } else if (Number(response.data.cacheAccesDefinition.id) === 1) {
                  this.$router.push({path: `/CacheEnd/${params.cacheID}`});
                }
              }).catch((error) => {
              console.log("resolve(false)");
              let header = "";
              let message = "";
              if (error.response) {
                console.log(error.response);
                header = "Falsche Station!";
                message = "Diese Station wurde schon gescannt, ist noch nicht an der Reihe oder gehört nicht zum Cache. ";
                message += "Bitte das Rätsel nochmal lesen und die richtige Station scannen.";
              } else if (error.request) {
                console.log(error.request);
                header = "Anfrage fehlgeschlagen!";
                message = "Die Verbindung zum Server ist gestört. Versuchen Sie es später noch einmal.";
              } else {
                console.log(error);
                console.log('Error', error.message);
                header = "Fehler!";
                message = error.message;
              }
              this.$store.commit('dialog/NEW_MESSAGE_DIALOG', { message: message, title: header, });
              resolve(false);
            });
          }
        })
      },

      setParams() {
        console.log("setParams: ");
        let params = {};
        if (localStorage.getItem('userToken')) {
          params.token = JSON.parse(localStorage.getItem('userToken')).token;
        }
        params.cacheID = this.result.split('/')[0];
        params.stationID = this.result.split('/')[1];
        params.durchgefuehrterCacheID = this.CacheID ? this.cacheID : params.cacheID;
        console.log(params.cacheID + " und " + params.stationID);
        this.updateProps();
        return params;
      },

      updateProps() {
        console.log("emit result!")
        this.$emit('result', this.params)
      },
      updateCameraState() {
        console.log("Camera State:")
        console.log(!this.askForPermission)
        this.$emit('camera', !this.askForPermission)
      },

      pauseCamera() {
        this.paused = true
      },

      unPauseCamera() {
        this.paused = false
      },

      toggleCamera(bool) {
        this.activateCamera = bool;
        if (this.askForPermission === false) {
          this.askForPermission = true;
          this.updateCameraState();
        }
      },

      logErrors(promise) {
        promise.catch(console.error)
      },

      async onInit(promise) {
        this.loading = true;
        try {
          await promise
        } catch (error) {
          if (error.name === 'StreamApiNotSupportedError') {
            this.noStreamApiSupport = true
          }
        } finally {
          this.loading = false;
          this.askForPermission = false;
          this.updateCameraState();

        }
      }
    },
    beforeRouteUpdate(to, from, next) {
      this.askForPermission = true;
      this.activateCamera = false;
      this.isValid = false;
      this.validating = false;
      this.loading = false;
      this.paused = false;
      this.result = null;
      this.params = null;
      this.noStreamApiSupport = false;
      this.setCacheId();
      next()
    },
  }
</script>

<style>
</style>
