<template>
  <div class="container">
    <h2 class="inquadra">
      Inquadra il qrcode
    </h2>
    <div class="camera">
      <qrcode-drop-zone @decode="onDecode" @init="logErrors">
        <qrcode-stream :camera="camera" @decode="onDecode" @init="onInit" />
      </qrcode-drop-zone>

      <qrcode-capture v-if="noStreamApiSupport" @decode="onDecode" />
    </div>
    <p v-if="isInvalid">non è un qrcode di ofo 😟</p>
    <p v-if="errored">si è verificato un errore, riprova!</p>
    <div v-if="loading" class="loading">⏳⏳⏳</div>
    <div class="decode-result" id="pin">
      <div
        class="decode-number"
        v-for="letter in split(bikePin)"
        v-bind:key="letter"
      >
        {{ letter }}
      </div>
    </div>
    <p v-if="bikePin">
      🔓inserisci il codice! ricordati che il codice è unico per ogni
      bicicletta, riusalo 😎
    </p>
  </div>
</template>

<script>
import { QrcodeStream, QrcodeDropZone, QrcodeCapture } from "vue-qrcode-reader";
import axios from "axios";
import VueScrollTo from "vue-scrollto";

export default {
  name: "Unlock",
  components: { QrcodeStream, QrcodeDropZone, QrcodeCapture },
  data() {
    return {
      result: "",
      error: "",
      loading: false,
      bikePin: "",
      errored: false,
      noStreamApiSupport: false,
      camera: "auto",
      isInvalid: undefined
    };
  },
  methods: {
    async onDecode(result) {
      this.bikePin = "";
      this.errored = false;
      this.turnCameraOff();
      if (result.startsWith("http://ofo.com/oneplate/")) {
        const code = +result.split("/").slice(-1);
        this.result = code;
        this.getCode(code);
      } else {
        this.isInvalid = true;
      }

      await this.timeout(3000);
      this.turnCameraOn();
      this.isInvalid = undefined;
    },
    logErrors(promise) {
      promise.catch(console.error);
    },
    async onInit(promise) {
      try {
        await promise;
      } catch (error) {
        if (error.name === "StreamApiNotSupportedError") {
          this.noStreamApiSupport = true;
        }
      }
    },
    resetValidationState() {
      this.isInvalid = undefined;
    },
    getCode(bikeId) {
      this.loading = true;
      axios
        .get("https://api.coindesk.com/v1/bpi/currentprice.json") //add here the api enpoint w/ bikeId param
        .then(response => {
          //const pin = response.data //get pin from api response
          const pin = "1234";
          this.bikePin = pin;
          VueScrollTo.scrollTo("#pin", 300);
        })
        .catch(error => {
          this.errored = true;
          this.result = "";
        })
        .finally(() => {
          this.result = "";
          this.loading = false;
        });
    },
    turnCameraOn() {
      this.camera = "auto";
    },

    turnCameraOff() {
      this.camera = "off";
    },
    timeout(ms) {
      return new Promise(resolve => {
        window.setTimeout(resolve, ms);
      });
    },
    split(text) {
      return text.split("");
    }
  }
};
</script>

<style scoped>
.container {
  max-width: 500px;
  height: 100%;
  padding: 15px;
  margin: 0 auto;
}

.camera {
  display: flex;
  align-items: center;
  justify-content: center;
}

.camera .wrapper::before {
  top: -6px;
  bottom: -6px;
  left: 45px;
  right: 45px;
  content: "";
  display: block;
  position: absolute;
  background: var(--yellow-ofo);
  z-index: 0;
}

.camera .wrapper::after {
  left: -6px;
  right: -6px;
  top: 45px;
  bottom: 45px;
  content: "";
  display: block;
  position: absolute;
  background: var(--yellow-ofo);
  z-index: 0;
}

.camera .wrapper {
  padding: 10px;
  border: 5px solid black;
  margin: 0 auto;
  border-radius: 5px;
  position: relative;
}

.error {
  font-weight: bold;
  color: red;
}

.inquadra,
.loading {
  text-align: center;
}

.inquadra {
  font-family: "syne", serif;
  font-weight: 700;
  text-transform: uppercase;
}

.decode-result {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 25px;
}

.decode-number {
  padding: 15px;
  border: 2px solid black;
  margin: 5px;
  font-weight: bold;
  font-size: 1.5rem;
}
</style>
