import Vuex from 'vuex'
import Vue from 'vue'
import createPersistedState from 'vuex-persistedstate'
import {getStoreBuilder} from 'vuex-typex'


import './modules/ui'
import './modules/authentication'
import './modules/feedback_list/feedback-search-options'
import './modules/feedback_list/feedback-table'
import './modules/subscriptions'
import './modules/submission-notes'
import './modules/student-page'

import './mutations'
import './actions'
import './getters'


import {UIState} from './modules/ui'
import {AuthState} from './modules/authentication'
import {FeedbackSearchOptionsState} from './modules/feedback_list/feedback-search-options'
import {SubscriptionsState} from './modules/subscriptions'
import {FeedbackTableState} from './modules/feedback_list/feedback-table'
import {SubmissionNotesState} from './modules/submission-notes'
import {StudentPageState} from './modules/student-page'

import {lastInteraction} from '@/store/plugins/lastInteractionPlugin'
import {
  Exam, Feedback,
  Statistics,
  StudentInfoForListView,
  SubmissionNoType,
  SubmissionType, Tutor
} from '@/models'

Vue.use(Vuex)

export interface RootInitialState {
    lastAppInteraction: number
    examTypes: {[pk: string]: Exam}
    feedback: {[pk: number]: Feedback}
    submissionTypes: {[pk: string]: SubmissionType}
    submissions: {[pk: string]: SubmissionNoType}
    students: {[pk: string]: StudentInfoForListView}
    studentMap: {} // is used to map obfuscated student data back to the original
    statistics: Statistics
    tutors: Array<Tutor>
}

export interface RootState extends RootInitialState{
  UI: UIState,
  Authentication: AuthState,
  FeedbackSearchOptions: FeedbackSearchOptionsState,
  FeedbackTable: FeedbackTableState,
  Subscriptions: SubscriptionsState,
  SubmissionNotes: SubmissionNotesState,
  StudentPage: StudentPageState
}

export function initialState (): RootInitialState {
  return {
    lastAppInteraction: Date.now(),
    examTypes: {},
    feedback: {},
    submissionTypes: {},
    submissions: {},
    students: {},
    studentMap: {}, // is used to map obfuscated student data back to the original
    statistics: {
      submissionsPerType: 0,
      submissionsPerStudent: 0,
      currentMeanScore: 0,
      submissionTypeProgress: []
    },
    tutors: []
  }
}

export const persistedStateKey = 'grady'

const store = getStoreBuilder<RootState>().vuexStore({
  strict: process.env.NODE_ENV === 'development',
  plugins: [
    createPersistedState({
      key: persistedStateKey,
      storage: window.sessionStorage,
      // Authentication.token is manually saved since using it with this plugin caused issues
      // when manually reloading the page
      paths: Object.keys(initialState()).concat(
        ['UI', 'StudentPage', 'SubmissionNotes', 'FeedbackSearchOptions', 'Subscriptions',
          'Authentication.user', 'Authentication.jwtTimeDelta',
          'Authentication.tokenCreationTime'])
    }),
    lastInteraction],
  // TODO is there a better way than casting the initialState ?
  state: <RootState> initialState()
})

export default store