import 'babel-polyfill'
import NProgress from 'nprogress'
import io from 'socket.io-client'

window.onload = () => {
  let div = document.createElement('div');
  div.innerHTML =
    `<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/styles/default.min.css">`;

  document.head.append(...div.children);
}
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import Vue from 'vue'
import Buefy from 'buefy'
import 'buefy/dist/buefy.css'
import axios from 'axios'
import VueAxios from 'vue-axios'
import VueFilterDateFormat from '@vuejs-community/vue-filter-date-format';
import 'core-js/stable';
import linkExpander from './assets/js/linkExpander'
import VueAnalytics from 'vue-analytics'
import App from './App'
import store from './store/index'
import VPaginator from 'vuejs-paginator'
import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faBell, faComment } from '@fortawesome/free-regular-svg-icons'
import {
  faBars, faPlus, faGrin, faLink, faCode,
  faTimes, faUnlockAlt, faReply, faHome, faTh,
  faExclamationCircle, faUserCircle, faThumbsUp,
  faComments, faUser, faCog, faLock, faCloudUploadAlt,
  faSearch, faChevronDown, faSortAmountUp, faSortAmountDown,
  faCheck, faQuoteRight, faMinus, faCaretUp, faCaretDown,
  faHeart
} from '@fortawesome/free-solid-svg-icons'

library.add(
  faBars, faPlus, faGrin, faLink, faCode,
  faTimes, faBell, faUnlockAlt, faReply, faHome,
  faTh, faExclamationCircle, faUserCircle, faThumbsUp,
  faComments, faUser, faCog, faLock, faCloudUploadAlt,
  faSearch, faChevronDown, faSortAmountUp, faSortAmountDown,
  faComment, faCheck, faQuoteRight, faMinus, faCaretUp, faCaretDown,
  faHeart
);
Vue.component('font-awesome-icon', FontAwesomeIcon);


const Index = () => import('./components/routes/Index')
const HomeUnauthenticated = () => import('./components/routes/HomeUnauthenticated')

const P = () => import('./components/routes/P')
const Thread = () => import('./components/routes/Thread')
const ThreadNew = () => import('./components/routes/ThreadNew')
const Games = () => import('./components/routes/Games')
const OutLink = () => import('./components/routes/OutLink')

const Search = () => import('./components/routes/Search')
const SearchUsersThreads = () => import('./components/routes/SearchUsersThreads')

const User = () => import('./components/routes/User')
const UserPosts = () => import('./components/routes/UserPosts')
const UserThreads = () => import('./components/routes/UserThreads')
const UserMarketplace = () => import('./components/routes/UserMarketplace')
const UsersList = () => import('./components/routes/UsersList')
const Banned = () => import('./components/routes/Banned')
const ToS = () => import('./components/routes/LegalToS')
const Privacy = () => import('./components/routes/LegalPrivacyPolicy')

const DeveloperPortal = () => import('./components/routes/DeveloperPortal')
const DeveloperDocs = () => import('./components/routes/DeveloperDocs')

const Hiring = () => import('./components/routes/Hiring')
const HiringApply = () => import('./components/routes/HiringApply')
const HiringThanks = () => import('./components/routes/HiringThanks')

const Settings = () => import('./components/routes/Settings')
const SettingsGeneral = () => import('./components/routes/SettingsGeneral')
const SettingsAccount = () => import('./components/routes/SettingsAccount')
const Character = () => import('./components/routes/Character')

const Admin = () => import('./components/routes/Admin')
const AdminDashboard = () => import('./components/routes/AdminDashboard')
const AdminModerationReports = () => import('./components/routes/AdminModerationReports')
const AdminModerationBannedUsers = () => import('./components/routes/AdminModerationBannedUsers')
const AdminGeneral = () => import('./components/routes/AdminGeneral')
const AdminUsers = () => import('./components/routes/AdminUsers')
const AdminOther = () => import('./components/routes/AdminOther')

const Licenses = () => import('./components/routes/LICENSES')

import NotFound from './components/routes/NotFound'
import Reserved from './components/routes/Reserved'
Vue.use(VueRouter)
Vue.use(Vuex)
Vue.use(VueAxios, axios)
Vue.use(linkExpander)
Vue.use(Buefy, { defaultIconPack: 'fas' })
Vue.use(VPaginator)
Vue.use(VueAnalytics, {
  id: 'UA-133165233-2',
  VueRouter
})
Vue.use(VueFilterDateFormat, {
  dayOfWeekNames: [
    'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
    'Friday', 'Saturday'
  ],
  dayOfWeekNamesShort: [
    'Su', 'Mo', 'Tu', 'We', 'Tr', 'Fr', 'Sa'
  ],
  monthNames: [
    'January', 'February', 'March', 'April', 'May', 'June',
    'July', 'August', 'September', 'October', 'November', 'December'
  ],
  monthNamesShort: [
    'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
  ],
  // Timezone offset, in minutes (0 - UTC, 180 - Russia, undefined - current)
  timezone: 0
});

Vue.use({
  install (Vue) {
    Vue.prototype.$socket = io();
  }
})

const router = new VueRouter({
  routes: [
    { path: '/', component: HomeUnauthenticated },
    { path: '/category/:category', component: Index },
    { path: '/p/:id', component: P },
    { path: '/start', component: Reserved },
    { path: '/blog', component: Reserved },
    { path: '/blog/:slug/:id', component: Reserved },
    { path: '/blog/:slug', component: Reserved },
    { path: '/jobs', component: Hiring },
    { path: '/jobs/apply', component: HiringApply },
    { path: '/jobs/thank-you', component: HiringThanks },
    { path: '/premium', component: Reserved },
    { path: '/upgrade', redirect: '/premium', component: Reserved },
    { path: '/experiments', component: Reserved },
    { path: '/thread/:slug/:id', component: Thread },
    { path: '/thread/:slug/:id/:post_number', name: 'thread-post', component: Thread },
    { path: '/thread/new', component: ThreadNew },
    { path: '/marketplace', component: Reserved },
    { path: '/licenses', component: Licenses },
    { path: '/games', component: Games },
    { path: '/game', redirect: '/games', component: Index },
    { path: '/gaming', redirect: '/games', component: Index },
    { path: '/legal/privacy', component: Privacy },
    { path: '/legal/guidelines', redirect: '/legal/tos',  component: ToS },
    { path: '/legal/tos', component: ToS },
    { path: '/g', redirect: '/games', component: Index },
    { path: '/out', redirect: '/', component: OutLink, children: [
        { path: '/out/https://*', redirect: 'https%3A%2F%2F*', component: OutLink },
        { path: '/out/http://*', redirect: 'http%3A%2F%2F*', component: OutLink },
        { path: '/out/:out*', component: OutLink }
      ] },
    { path: '/users', component: UsersList },
    { path: '/developers', redirect: '/developers/portal', component: DeveloperPortal, children: [
        { path: 'portal', component: DeveloperPortal },
        { path: 'docs', component: DeveloperDocs },
      ] },
    { path: '/forum', redirect: '/category/all', component: Index },
    { path: '/forums', redirect: '/category/all', component: Index },
    { path: '/search/:q', component: Search },
    { path: '/search/users/:q', component: SearchUsersThreads, name: 'search/users' },
    { path: '/search/threads/:q', component: SearchUsersThreads, name: 'search/threads' },
    { path: '/user/:username', redirect: '/user/:username/posts', component: User, children: [
        { path: 'posts', component: UserPosts },
        { path: 'threads', component: UserThreads },
        { path: 'items', component: UserMarketplace }
      ] },
    { path: '/settings', redirect: '/settings/general', component: Settings, children: [
        { path: 'general', component: SettingsGeneral },
        { path: 'account', component: SettingsAccount }
      ] },
    { path: '/character', component: Character, name: 'character' },
    { path: '/banned', component: Banned },
    { path: '/admin', redirect: '/admin/dashboard', component: Admin, children: [
        { path: 'dashboard', component: AdminDashboard },
        { path: 'general', component: AdminGeneral },
        { path: 'users', component: AdminUsers },
        { path: 'moderation', redirect: '/admin/moderation/reports' },
        { path: 'moderation/reports', component: AdminModerationReports },
        { path: 'moderation/bans', component: AdminModerationBannedUsers },
        { path: 'other', component: AdminOther },
      ] },
    { path: '*', component: NotFound }
  ],
  mode: 'history'
})

router.beforeEach((to, from, next) => {
  router.app.$store.commit('set404Page', false)

  //Do not change progress bar when scrolling through posts on a thread
  if(
    (to.name !== 'thread-post' && from.name !== 'thread-post') &&
    (!to.params.id || to.params.id !== from.params.id)
  ) {
    NProgress.start()
  }

  next()
})
router.afterEach(() => {
  NProgress.done()
})

Vue.filter('formatDate', function (value) {
  if(typeof value !== 'object') {
    value = new Date(value)
  }

  //Add leading zero if under 10
  function lz(num) {
    if(num < 10) {
      return '0' + num;
    } else {
      return '' + num;
    }
  }

  //2 minutes
  return (
    'Created on ' +
    lz(value.getDate()) + '/' +
    lz(value.getMonth() + 1) + '/' +
    value.getUTCFullYear()
  );
});

Vue.filter('stripTags', function (value) {
  let doc = new DOMParser().parseFromString(value, 'text/html')
  return doc.body.textContent || ''
});

Vue.filter('truncate', function (value, length) {
  if(value.length <= length) {
    return value
  } else {
    return value.slice(0, length) + '…'
  }
});
Vue.filter('truncateMid', function (value, length) {
  if(value.length <= length) {
    return value
  } else {
    let firstLen = Math.round(length/2);
    let secondLen = length - firstLen;

    return value.slice(0, firstLen) + '…' + value.slice(value.length-secondLen, value.length)
  }
});

Vue.filter('pluralize', function(number, value) {
  if(number === 1) {
    return value
  } else {
    return value + 's'
  }
})

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


let cookieDict = document.cookie
  .split(';')
  .map(a => a.split('=').map(a => a.trim()) )
  .map(a => {
    let k = a[0], v = a[1]
    return { [k] : v }
  })
  .reduce((combinedObj, o) => {
    let key = Object.keys(o)[0]
    combinedObj[key] = o[key]

    return combinedObj
  }, {})

if(cookieDict.username) Root.$store.commit('setUsername', cookieDict.username)
if(cookieDict.admin === 'false') {
  Root.$store.commit('setAdmin', false)
} else if(cookieDict.admin === 'true') {
  Root.$store.commit('setAdmin', true)
}
