import 'babel-polyfill';
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import VueRouter from 'vue-router';
import App from './App.vue';
import messages from './lang';
import shared from './shared';
import fontawesome from '@fortawesome/fontawesome';
import FontAwesomeIcon from '@fortawesome/vue-fontawesome';
import moment from 'moment'
import merge from 'lodash/merge';

// Implicitly import the icons used, saves a lot of space in the bundle.
// Perhaps vue-fontawesome will make this easier in the upcoming release?
// See: https://github.com/FortAwesome/vue-fontawesome/issues/46
import faSpinner from '@fortawesome/fontawesome-free-solid/faSpinner';
import faBan from '@fortawesome/fontawesome-free-solid/faBan';
import faTrashAlt from '@fortawesome/fontawesome-free-solid/faTrashAlt';
import faUser from '@fortawesome/fontawesome-free-solid/faUser';
import faSquare from '@fortawesome/fontawesome-free-regular/faSquare';
import faCheckSquare from '@fortawesome/fontawesome-free-regular/faCheckSquare';


if (typeof customMessages !== 'undefined')
{
  merge(messages, customMessages);

  if (customMessages.hasOwnProperty('allLocales'))
  {
    for (var key in messages)
    {
      if (key !== 'allLocales' && messages.hasOwnProperty(key))
        merge(messages[key], customMessages.allLocales);
    }
  }
}


fontawesome.library.add(faSpinner, faBan, faTrashAlt, faUser, faSquare, faCheckSquare);
Vue.component('fa', FontAwesomeIcon);

Vue.use(VueI18n);
Vue.use(VueRouter);

const i18n = new VueI18n({
  locale: navigator.language ? navigator.language.split('-')[0] : null,
  fallbackLocale: 'en',
  messages: messages
});


Vue.filter('formatDateTime', (value) =>
{
  if (value)
  {
    return moment(String(value)).format(i18n.t('dateTimeFormat'))
  }
});

Vue.filter('formatDate', (value) =>
{
  if (value)
  {
    return moment(String(value)).format(i18n.t('dateFormat'))
  }
});

Vue.filter('formatTime', (value) =>
{
  if (value)
  {
    return moment(String(value)).format(i18n.t('timeFormat'))
  }
});

// All credit goes to: https://stackoverflow.com/a/14919494
function humanFileSize(bytes, si)
{
  var thresh = si ? 1000 : 1024;
  if(Math.abs(bytes) < thresh)
  {
    return bytes + ' B';
  }

  var units = si
    ? ['kB','MB','GB','TB','PB','EB','ZB','YB']
    : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
  var u = -1;

  do
  {
    bytes /= thresh;
    ++u;
  }
  while(Math.abs(bytes) >= thresh && u < units.length - 1);

  return bytes.toFixed(1) + ' ' + units[u];
}

Vue.filter('formatSize', (value) =>
{
  return humanFileSize(value, false);
});

Vue.filter('formatSizeSI', (value) =>
{
  return humanFileSize(value, true);
});


const Code = () => import('./route/Code.vue');
const AdminCodeDetail = () => import('./route/admin/CodeDetail.vue');
const AdminUserDetail = () => import('./route/admin/UserDetail.vue');


const router = new VueRouter({
  routes: [
    { path: '/', component: () => import('./route/Landing.vue'),
      children: [
        { path: 'c/:codeParam', component: Code, props: true },
        { path: 'u/:codeParam', component: () => import('./route/Upload.vue'), props: true },
        { path: '', component: Code }
      ]
    },
    { path: '/admin', component: () => import('./route/admin/Landing.vue'),
      children: [
        { path: 'uploads', name: 'adminDefault', component: () => import('./route/admin/Uploads.vue') },
        { path: 'codes/add', component: AdminCodeDetail },
        { path: 'codes/edit/:codeParam', component: AdminCodeDetail, props: true },
        { path: 'codes', component: () => import('./route/admin/Codes.vue') },
        { path: 'profile', component: () => import('./route/admin/Profile.vue') },
        { path: 'users/add', component: AdminUserDetail },
        { path: 'users/edit/:idParam', component: AdminUserDetail, props: true },
        { path: 'users', component: () => import('./route/admin/Users.vue') },
        { path: '', name: 'adminRoot', component: () => import('./route/admin/Login.vue') }
      ]
    },
    { path: '*', redirect: '/' }
  ]
});


router.beforeEach((to, from, next) =>
{
  let isAdminRoot = to.name == 'adminRoot';

  if (to.path.substring(0, 7) == '/admin/' && !isAdminRoot)
  {
    if (!shared.adminToken)
    {
      router.push({ name: 'adminRoot' });
      return;
    }
  }
  else if (isAdminRoot && shared.adminToken)
  {
    router.push({ name: 'adminDefault' });
    return;
  }

  next();
});


new Vue({
  el: '#app',
  i18n,
  router,
  render: h => h(App)
});