Vue.config.devtools = true
const app = new Vue({
  computed: {
    clock() {
      return moment(this.time).format('HH:mm:ss')
    },

    icons() {
      const icons = []

      if (!this.conn.avail) {
        icons.push({ class: 'fas fa-ethernet text-warning' })
      }

      return icons
    },

    nextFollowers() {
      return Math.ceil((this.store.followers.count + 1) / 25) * 25
    },

    nextSubs() {
      return Math.ceil((this.store.subs.count + 1) / 5) * 5
    },
  },

  created() {
    window.setInterval(() => { this.time = new Date() }, 1000)
    this.startSocket()

    this.sound = new Audio()
    this.sound.addEventListener('load', () => this.sound.play(), true)
    this.sound.autoplay = true
  },

  data: {
    conn: {
      avail: false,
      backoff: 100,
    },
    firstLoad: true,
    sound: null,
    store: {},
    socket: null,
    time: new Date(),
    version: null,
  },

  el: '#app',

  methods: {
    playSound(soundUrl) {
      this.sound.src = soundUrl
    },

    showAlert(title, text, variant) {
      this.$bvToast.toast(text, {
        title,
        toaster: 'b-toaster-top-right',
        variant: variant || 'primary',
      })
    },

    startSocket() {
      if (this.socket) {
        // Dispose old socket
        this.socket.close()
        this.socket = null
      }

      let socketAddr = `${window.location.origin.replace(/^http/, 'ws')}/api/subscribe`

      this.socket = new WebSocket(socketAddr)
      this.socket.onclose = () => {
        this.conn.avail = false
        this.conn.backoff = Math.min(this.conn.backoff * 1.25, 10000)
        window.setTimeout(this.startSocket, this.conn.backoff) // Restart socket
      }
      this.socket.onmessage = evt => {
        const data = JSON.parse(evt.data)

        if (data.version) {
          this.version = data.version
        }

        switch (data.type) {
          case 'alert':
            this.showAlert(data.payload.title, data.payload.text, data.payload.variant)
            if (data.payload.sound) {
              this.playSound(data.payload.sound)
            }
            break

          case 'host':
            this.showAlert('Incoming host', `${data.payload.from} just hosted`)
            break

          case 'raid':
            this.showAlert('Incoming raid', `${data.payload.from} just raided with ${data.payload.viewerCount} raiders`)
            break

          case 'store':
            this.store = data.payload
            window.setTimeout(() => { this.firstLoad = false }, 100) // Delayed to let the watches trigger
            break

          default:
            console.log(`Unhandled message type ${data.type}`, data)
        }
      }
      this.socket.onopen = evt => {
        this.conn.avail = true
        this.conn.backoff = 100
      }
    },
  },

  watch: {
    'store.followers.last'(to, from) {
      if (this.firstLoad || !to) {
        // Initial load or no follower
        return
      }
      this.showAlert('New Follower', `${to} just followed`, 'success')
      this.playSound('/public/doorbell.webm')
    },

    version(to, from) {
      if (!from || !to || from === to) {
        return
      }
      window.location.reload()
    },
  },
})