import 'babel-polyfill'
import NProgress from 'nprogress'
import io from 'socket.io-client'
import "core-js/stable";

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 './assets/buefy/buefy.css'
import Buefy from 'buefy'
import axios from 'axios'
import VueAxios from 'vue-axios'
import 'core-js/stable';
import linkExpander from './assets/js/linkExpander'
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 * as Sentry from "@sentry/browser";
import { Vue as VueIntegration } from "@sentry/integrations";
import { Integrations } from '@sentry/tracing';
import { faBell, faComment } from '@fortawesome/free-regular-svg-icons'
import VueMatomo from 'vue-matomo'
import { VueSpinners } from '@saeris/vue-spinners'
import moment from 'moment'
import VueSkipTo from '@vue-a11y/skip-to'

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 CategorySelect = () => import('./components/routes/CategorySelect')
const Home = () => import('./components/routes/Home')
const HomeAuthenticated = () => import('./components/routes/HomeAuthenticated')

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 Teams = () => import('./components/routes/Teams')
const Team = () => import('./components/routes/Team')
const TeamSettings = () => import('./components/routes/TeamSettings')
const TeamRoles = () => import('./components/routes/TeamRoles')
const TeamGeneral = () => import('./components/routes/TeamGeneral')
const TeamPrivacy = () => import('./components/routes/TeamPrivacy')
const TeamRequests = () => import('./components/routes/TeamRequests')
const TeamUsers = () => import('./components/routes/TeamUsers')
const TeamWall = () => import('./components/routes/TeamWall')
const TeamMembers = () => import('./components/routes/TeamMembers')
const TeamInvite = () => import('./components/routes/TeamInvite')
const TeamInvites = () => import('./components/routes/TeamInvites')

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 UserWall = () => import('./components/routes/UserWall')
const UserInventory = () => import('./components/routes/UserInventory')
const UsersList = () => import('./components/routes/UsersList')
const Notifications = () => import('./components/routes/Notifications')
const Banned = () => import('./components/routes/Banned')
const ToS = () => import('./components/routes/LegalToS')
const Privacy = () => import('./components/routes/LegalPrivacyPolicy')
const EmailVerify = () => import('./components/routes/EmailVerify')
const EmailVerifyCheck = () => import('./components/routes/EmailVerifyCheck')
const EmailVerifySuccess = () => import('./components/routes/EmailVerifySuccess')
const EmailVerifyError = () => import('./components/routes/EmailVerifyError')
const DeleteUndoCode = () => import('./components/routes/DeleteUndoCode')
const DeleteVerify = () => import('./components/routes/DeleteVerify')
const DeleteError = () => import('./components/routes/DeleteError')

const Recovery = () => import('./components/routes/Recovery')

const Chat = () => import('./components/routes/Chat')
const Conversation = () => import('./components/routes/Conversation')

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 SettingsExperiments = () => import('./components/routes/SettingsExperiments')
const SettingsAbout = () => import('./components/routes/SettingsAbout')
const SettingsPrivacy = () => import('./components/routes/SettingsPrivacy')
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 AdminBadges = () => import('./components/routes/AdminAudit')
const AdminApplications = () => import('./components/routes/AdminApplications')
const AdminPrivileges = () => import('./components/routes/AdminPrivileges')
const AdminTeams = () => import('./components/routes/AdminTeams')
const AdminMarketplace = () => import('./components/routes/AdminMarketplace')

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

const Inventory = () => import('./components/routes/Inventory')

const Marketplace = () => import('./components/routes/Marketplace')
const MarketplaceCreate = () => import('./components/routes/MarketplaceCreate')
const MarketplaceItem = () => import('./components/routes/MarketplaceItem')
const MarketplaceItemAuction = () => import('./components/routes/MarketplaceItemAuction')
const TransactionLog = () => import('./components/routes/TransactionLog')

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(VueSpinners)
Vue.use(VueSkipTo)
Sentry.init({
  dsn: "https://287b35aa71b54ffea9e66b5ce03d2e29@o444992.ingest.sentry.io/5420646",
  integrations: [
    new VueIntegration({
      Vue,
      tracing: true
    }),
    new Integrations.BrowserTracing()
  ],
  tracesSampleRate: 1
});
Vue.use({
  install (Vue) {
    Vue.prototype.$socket = io(process.env.VUE_APP_GATEWAYENDPOINT)
  }
})

const router = new VueRouter({
  routes: [
    { path: '/', component: Home },
    { path: '/dashboard', redirect: '/', component: HomeAuthenticated },
    { path: '/category/select', component: CategorySelect },
    { 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: Marketplace },
    { path: '/marketplace/create', component: MarketplaceCreate },
    { path: '/transactions', component: TransactionLog },
    { path: '/m/:id', component: MarketplaceItem, children: [
        { path: 'auction', component: MarketplaceItemAuction }
        ] },
    { path: '/licenses', component: Licenses },
    { path: '/teams', component: Teams },
    { path: '/team/:username', redirect: '/team/:username/general', component: TeamSettings, children: [
        { path: 'general', component: TeamGeneral },
        { path: 'users', component: TeamUsers },
        { path: 'roles', component: TeamRoles },
        { path: 'privacy', component: TeamPrivacy },
        { path: 'requests', component: TeamRequests },
        { path: 'invites', component: TeamInvites }
      ] },
    { path: '/t/:username', component: Team, children: [
        { path: 'items', component: UserMarketplace },
        { path: 'wall', component: TeamWall },
        { path: 'members', component: TeamMembers }
      ] },
    { path: '/verify', component: EmailVerify },
    { path: '/verify/check', component: EmailVerifyCheck },
    { path: '/verify/error', component: EmailVerifyError },
    { path: '/verify/success', component: EmailVerifySuccess },
    { path: '/delete/', component: DeleteVerify },
    { path: '/delete/undo', component: DeleteUndoCode },
    { path: '/delete/error', component: DeleteError },
    { path: '/recovery', component: Recovery },
    { 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: '?uri=https%3A%2F%2F*', component: OutLink },
        { path: '/out/http://*', redirect: '?uri=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: '/connection', component: ConnectionProblems },
    { path: '/maintenance', component: Maintenance },
    { path: '/contributors', component: Contributors },
    { 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', component: User, redirect: '/u/:username' },
    { path: '/user/:username/posts', component: User, redirect: '/u/:username/posts' },
    { path: '/user/:username/threads', component: User, redirect: '/u/:username/threads' },
    { path: '/user/:username/items', component: User, redirect: '/u/:username/items' },
    { path: '/user/:username/wall', component: User, redirect: '/u/:username/wall' },
    { path: '/invite/:code', component: TeamInvite },
    { path: '/notifications', component: Notifications },
    { path: '/inventory', component: Inventory },
    {
      path: '/chat',
      component: Chat,
      children: [
        { path: '/', component: Chat },
        { path: 'conversation', component: Conversation },
        { path: 'conversation/:id', component: Conversation, name: 'conversation' }
      ]
    },
    { path: '/u/:username', redirect: '/u/:username/posts', component: User, children: [
        { path: 'posts', component: UserPosts },
        { path: 'threads', component: UserThreads },
        { path: 'items', component: UserMarketplace },
        { path: 'wall', component: UserWall },
        { path: 'inventory', component: UserInventory }
      ] },
    { path: '/settings', redirect: '/settings/general', component: Settings, children: [
        { path: 'general', component: SettingsGeneral },
        { path: 'account', component: SettingsAccount },
        { path: 'experiments', component: SettingsExperiments },
        { path: 'about', component: SettingsAbout },
        { path: 'privacy', component: SettingsPrivacy }
      ] },
    { 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: 'logs', component: AdminBadges },
        { path: 'applications', component: AdminApplications },
        { path: 'privileges', component: AdminPrivileges },
        { path: 'teams', component: AdminTeams },
        { path: 'marketplace', component: AdminMarketplace },
      ] },
    { 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 (value) {
    return moment(String(value)).format('hh:mm A, DD/MM/YYYY')
  }
})
Vue.filter('strLimit', function (value, size) {
  if (!value) return '';
  value = value.toString();

  if (value.length <= size) {
    return value;
  }
  return value.substr(0, size) + '...';
});
Vue.use(VueMatomo, {
  // Configure your matomo server and site by providing
  host: 'https://analytics.troplo.com',
  siteId: 1,

  // Changes the default .js and .php endpoint's filename
  // Default: 'matomo'
  trackerFileName: 'troplo',

  // Overrides the autogenerated tracker endpoint entirely
  // Default: undefined
  // trackerUrl: 'https://example.com/whatever/endpoint/you/have',

  // Overrides the autogenerated tracker script path entirely
  // Default: undefined
  // trackerScriptUrl: 'https://example.com/whatever/script/path/you/have',

  // Enables automatically registering pageviews on the router
  router: router,

  // Enables link tracking on regular links. Note that this won't
  // work for routing links (ie. internal Vue router links)
  // Default: true
  enableLinkTracking: true,

  // Require consent before sending tracking information to matomo
  // Default: false
  requireConsent: false,

  // Whether to track the initial page view
  // Default: true
  trackInitialView: true,

  // Run Matomo without cookies
  // Default: false
  disableCookies: false,

  // Enable the heartbeat timer (https://developer.matomo.org/guides/tracking-javascript-guide#accurately-measure-the-time-spent-on-each-page)
  // Default: false
  enableHeartBeatTimer: false,

  // Set the heartbeat timer interval
  // Default: 15
  heartBeatTimerInterval: 15,

  // Whether or not to log debug information
  // Default: false
  debug: false,

  // UserID passed to Matomo (see https://developer.matomo.org/guides/tracking-javascript-guide#user-id)
  // Default: undefined
  userId: undefined,

  // Share the tracking cookie across subdomains (see https://developer.matomo.org/guides/tracking-javascript-guide#measuring-domains-andor-sub-domains)
  // Default: undefined, example '*.example.com'
  cookieDomain: undefined,

  // Tell Matomo the website domain so that clicks on these domains are not tracked as 'Outlinks'
  // Default: undefined, example: '*.example.com'
  domains: undefined,

  // A list of pre-initialization actions that run before matomo is loaded
  // Default: []
  // Example: [
  //   ['API_method_name', parameter_list],
  //   ['setCustomVariable','1','VisitorType','Member'],
  //   ['appendToTrackingUrl', 'new_visit=1'],
  //   etc.
  // ]
  preInitActions: []
});
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)
}
