import Keycloak from 'keycloak-js'
import Vue from 'vue'

import 'element-ui/lib/theme-chalk/index.css'
import './scss/index.scss'

import Element from 'element-ui'

import App from './App'
import store from './store'
import router from './router'

import './icons'
import './components'
import './permission'

import {
  showLoading,
  closeLoading
} from './utils/pop'

const initOptions = {
  url: process.env.VUE_APP_KEYCLOAK_OPTIONS_URL,
  realm: process.env.VUE_APP_KEYCLOAK_OPTIONS_REALM,
  clientId: process.env.VUE_APP_KEYCLOAK_OPTIONS_CLIENTID,
  onLoad: process.env.VUE_APP_KEYCLOAK_OPTIONS_ONLOAD
}

const keycloak = Keycloak(initOptions)

keycloak
  .init({ onLoad: initOptions.onLoad })
  .then(auth => {
    if (!auth) {
      console.error('Authenticated Failed[403]')
      return
    }

    console.log(keycloak)

    // Token Refresh
    setInterval(() => {
      keycloak.updateToken(70).then(refreshed => {
        if (refreshed) {
          console.info('Token refreshed', keycloak)
          store.commit('user/SET_TOKEN', keycloak.token)
        } else {
          console.warn(`Token not refreshed, valid for ${Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000)} seconds`)
        }
      }).catch(() => console.error('Failed to refresh token'))
    }, 6000)
  })
  .catch(() => console.error('Authenticated Failed'))
  .finally(startApp)

async function startApp () {
  document.body.setAttribute('version', __VERSION__)

  Vue.use(Element)
  Vue.prototype.$keycloak = keycloak
  Vue.prototype.$showLoading = showLoading
  Vue.prototype.$closeLoading = closeLoading

  Vue.prototype.__STAGING__ = __STAGING__
  Vue.prototype.__PLACEHOLDER__ = __PLACEHOLDER__

  Vue.config.productionTip = false
  Vue.config.errorHandler = err => {
    closeLoading()
    throw err
  }

  await store.dispatch('user/login', keycloak)
  store.dispatch('permission/generateRoutes', {
    roles: store.getters.roles,
    accesses: store.getters.accesses
  })
  router.addRoutes(store.getters.permissionRoutes)

  Vue.prototype.roleSet = store.getters.roles
  Vue.prototype.accessSet = store.getters.accesses

  new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount('#app')
}
