<template>
  <b-toast
    v-if="!autoRefresh"
    id="app-update-toast"
    variant="warning"
    solid
    v-model="updateExists"
    no-close-button
    toaster="b-toaster-top-right"
    no-auto-hide
  >
    <template v-slot:toast-title>
      <div class="d-flex flex-grow-1 align-items-baseline">
        <b-img blank blank-color="#ff5555" class="mr-2" width="12" height="12" />
        <strong class="mr-auto">{{ $t('Common.Notice') }}</strong>
        <small class="text-muted mr-2">{{ updateCreatedOn }}</small>
      </div>
    </template>
    <b-row align-h="between" align-v="center">
      <b-col cols="auto">
        {{ $t('Version.New') }} <br />
        <small>{{ $t('Version.Update.ForceUpdate.Info', { time: timer }) }}</small>
      </b-col>
      <b-col cols="auto">
        <b-button pill class="animated pulse infinite" variant="black" @click="refreshApp">{{
          $t('Version.UpdateNow')
        }}</b-button>
      </b-col>
    </b-row>
  </b-toast>
</template>
<script>
import appSettings from '@/config/app-settings'
import { APP_UPDATED_TIMESTAMP } from '@/store/utils/localStorageKeys'
import moment from 'moment'
import momentDurationFormatSetup from 'moment-duration-format'

momentDurationFormatSetup(moment)

export default {
  name: 'UpdateNotification',
  props: {
    autoRefresh: {
      type: Boolean,
      default: appSettings.updateNotification.autoRefresh,
    },
  },
  data() {
    return {
      refreshing: false,
      registration: null,
      updateExists: false,
      timer: '0:00:00',
      updateCreatedOn: '',
      timerDeadlineLimit: appSettings.updateNotification.timerDeadlineLimit, // seconds
      updateInterval: 1000,
    }
  },
  methods: {
    processTimer() {
      let autoUpdateDeadLineTimestamp = Number(localStorage.getItem(APP_UPDATED_TIMESTAMP) || 0)
      let currentTime = Math.floor(Date.now() / 1000)
      let diffTime = autoUpdateDeadLineTimestamp - currentTime
      let duration = moment.duration(diffTime * 1000, 'milliseconds')
      let interval = 1000
      this.timer = moment.duration(duration - interval, 'milliseconds').format('hh:mm:ss')
      this.updateCreatedOn = moment.duration((diffTime - this.timerDeadlineLimit) * 1000, 'milliseconds').humanize(true)
      // Invoke force refresh if user stay idle
      if (autoUpdateDeadLineTimestamp !== 0) {
        // todo remove once stable
        // for testing if update timestamp exist show notification
        this.updateExists = true
        if (currentTime > autoUpdateDeadLineTimestamp) {
          this.refreshApp()
        }
      }
    },
    showRefreshUI(e) {
      // On service-worker updated show update notification to user
      if (!localStorage.getItem(APP_UPDATED_TIMESTAMP)) {
        let updateReceivedTimestamp = Math.floor(Date.now() / 1000 + this.timerDeadlineLimit)
        localStorage.setItem(APP_UPDATED_TIMESTAMP, JSON.stringify(updateReceivedTimestamp))
      }
      this.registration = e.detail
      if (!this.autoRefresh) {
        this.updateExists = true
      } else {
        this.refreshApp()
      }
    },
    refreshApp() {
      this.updateExists = false
      localStorage.removeItem(APP_UPDATED_TIMESTAMP)
      if (!this.registration || !this.registration.waiting) return
      // send message to SW to skip the waiting and activate the new SW
      this.registration.waiting.postMessage('skipWaiting')
    },
  },
  created() {
    // Reload browser
    this.$nextTick(() => {
      // when a new service worker is available
      document.addEventListener('swUpdated', this.showRefreshUI, { once: true })
      if (typeof navigator.serviceWorker !== 'undefined') {
        navigator.serviceWorker.addEventListener('controllerchange', () => {
          if (this.refreshing) return
          this.refreshing = true
          // Here the actual reload of the page occurs
          window.location.reload()
        })
      }
      // Update timer on interval
      setInterval(() => this.processTimer(), this.updateInterval)
    })
  },
}
</script>
