/* global Vue */

import EventClient from './eventclient.js'

new Vue({
  created() {
    this.createAudioInterface()

    new EventClient({
      handlers: {
        custom: ({ fields }) => this.handleCustom(fields),
      },
    })
  },

  data: {
    alerts: [],
    alertsEnabled: true,
    sound: null,
    soundsActive: false,
  },

  el: '#app',

  methods: {
    createAudioInterface() {
      // Create basic audio element to play sound
      this.sound = new Audio()

      this.sound.addEventListener('load', () => this.sound.play(), true)
      this.sound.addEventListener('playing', () => {
        this.soundsActive = true
      })
      this.sound.addEventListener('pause', () => {
        this.soundsActive = false
      })
      this.sound.autoplay = true
      this.sound.crossOrigin = 'anonymous'

      // Create limiter chain and connect audio element to it
      const audioCtx = new AudioContext()

      const preGainNode = audioCtx.createGain()
      // preGainNode.gain.setValueAtTime(-0.5, audioCtx.currentTime) // Decibel

      const masterGainNode = audioCtx.createGain()
      masterGainNode.gain.setValueAtTime(-0.1, audioCtx.currentTime) // Decibel

      const limiterNode = audioCtx.createDynamicsCompressor()
      limiterNode.threshold.setValueAtTime(-30.0, audioCtx.currentTime) // Decibel
      limiterNode.knee.setValueAtTime(0, audioCtx.currentTime) // Decibel
      limiterNode.ratio.setValueAtTime(20.0, audioCtx.currentTime) // Decibel
      limiterNode.attack.setValueAtTime(0, audioCtx.currentTime) // Seconds
      limiterNode.release.setValueAtTime(0.1, audioCtx.currentTime) // Seconds

      preGainNode.connect(limiterNode)
      limiterNode.connect(masterGainNode)
      masterGainNode.connect(audioCtx.destination)

      const source = audioCtx.createMediaElementSource(this.sound)
      source.connect(preGainNode)
    },

    handleCustom(data) {
      switch (data.type) {
      case 'soundalert':
        this.queueAlert({
          soundUrl: data.soundUrl,
        })
        break

      default:
        console.log(`Unhandled custom event ${data.type}`, data)
      }
    },

    playSound(soundUrl) {
      this.soundsActive = true
      this.sound.src = soundUrl
    },

    queueAlert(alertParams) {
      this.alerts.push(alertParams)
    },

    triggerAlert() {
      const alrt = this.alerts.shift()
      if (!alrt) {
        return
      }

      if (!this.alertsEnabled) {
        // Alerts are disabled completely or this one is blocked, discard alert
        return this.triggerAlert()
      }

      if (alrt.soundUrl) {
        this.playSound(alrt.soundUrl)
      }
    },
  },

  name: 'SoundOverlay',

  watch: {
    alerts(to) {
      if (to.length > 0 && !this.alertsRunning) {
        this.triggerAlert()
      }
    },

    soundsActive(to) {
      if (!to) {
        this.triggerAlert()
      }
    },
  },
})