import Reflux from 'reflux'
import Immutable from 'immutable'

import Student from '../models/student'

import studentActions from './studentActions'

let studentStore = Reflux.createStore({
	listenables: studentActions,

	init() {
		this.students = Immutable.Map()
		this.history = Immutable.Stack()
		this.future = Immutable.Stack()

		this._loadData()
	},

	getInitialState() {
		return this.students
	},

	undo() {
		this.future = this.future.unshift(this.history.first())
		this.students = this.history.shift()
		this._postChange()
	},

	redo() {
		if (this.future.size) {
			this.history = this.future
			this.students = this.future.shift()
			this._postChange()
		}
	},

	_loadData(opts={}) {
		console.log('studentStore._loadData, with', opts)
		let rawStudent = null
		let studentId = localStorage.getItem('activeStudentId')
		let demoStudentId = '3AE9E7EE-DA8F-4014-B987-8D88814BB848'

		let localStudent = localStorage.getItem(studentId || demoStudentId) || localStorage.getItem('student-v3.0a6')

		try {
			rawStudent = JSON.parse(localStudent)
		}
		catch (e) {
			console.info('using demo student')
			rawStudent = demoStudent
			rawStudent.active = true
			rawStudent.id = null
		}

		let student = new Student(rawStudent)
		window.studentData = student

		this._preChange()
		this.students = this.students.set(student.id, student)
		this._postChange()
	},

	_preChange() {
		this.history = this.history.unshift(this.students)
	},

	_postChange() {
		console.groupCollapsed('studentStore._postChange')
		console.log('studentStore._postChange', this.students)
		this.students.forEach(student => student.save())
		console.groupEnd('studentStore._postChange')
		this.trigger(this.students)
	},

	_change(studentId, method, ...args) {
		this._preChange()
		this.students = this.students.set(studentId, this.students.get(studentId)[method](...args))
		this._postChange()
	},

	_alter(pathToData, method, ...args) {
		this._preChange()
		this.students = this.students.setIn(pathToData, this.students.getIn(pathToData)[method](...args))
		this._postChange()
	},

	changeName(studentId, ...args)               { this._change(studentId, 'changeName',               ...args) },
	changeActive(studentId, ...args)             { this._change(studentId, 'changeActive',             ...args) },
	changeCreditsNeeded(studentId, ...args)      { this._change(studentId, 'changeCreditsNeeded',      ...args) },
	changeMatriculation(studentId, ...args)      { this._change(studentId, 'changeMatriculation',      ...args) },
	changeGraduation(studentId, ...args)         { this._change(studentId, 'changeGraduation',         ...args) },
	changeSetting(studentId, key, value)         { this._change(studentId, 'changeSetting',            key, value) },
	addArea(studentId, ...args)                  { this._change(studentId, 'addArea',                  ...args) },
	addSchedule(studentId, ...args)              { this._change(studentId, 'addSchedule',              ...args) },
	addFabrication(studentId, ...args)           { this._change(studentId, 'addArea',                  ...args) },
	addOverride(studentId, ...args)              { this._change(studentId, 'addSchedule',              ...args) },
	removeArea(studentId, ...args)               { this._change(studentId, 'removeArea',               ...args) },
	removeMultipleAreas(studentId, ...args)      { this._change(studentId, 'removeMultipleArea',       ...args) },
	destroySchedule(studentId, ...args)          { this._change(studentId, 'destroySchedule',          ...args) },
	destroyMultipleSchedules(studentId, ...args) { this._change(studentId, 'destroyMultipleSchedules', ...args) },

	renameSchedule(studentId, scheduleId, ...args)  { this._alter([studentId, 'schedules', scheduleId], 'rename',        ...args) },
	reorderSchedule(studentId, scheduleId, ...args) { this._alter([studentId, 'schedules', scheduleId], 'reorder',       ...args) },
	moveSchedule(studentId, scheduleId, ...args)    { this._alter([studentId, 'schedules', scheduleId], 'move',          ...args) },
	addCourse(studentId, scheduleId, ...args)       { this._alter([studentId, 'schedules', scheduleId], 'addCourse',     ...args) },
	removeCourse(studentId, scheduleId, ...args)    { this._alter([studentId, 'schedules', scheduleId], 'removeCourse',  ...args) },
	reorderCourse(studentId, scheduleId, ...args)   { this._alter([studentId, 'schedules', scheduleId], 'reorderCourse', ...args) },
	reorderArea(studentId, areaId, ...args)         { this._alter([studentId, 'studies', areaId],       'reorder',       ...args) },
})

window.store = studentStore

export default studentStore

@@ -418,42 +418,130 @@
 %7B%0A%09%09
-this.future = this.future.unshift(
+if (this.history.size) %7B%0A%09%09%09console.log('undoing...')%0A%09%09%09this.future = this.future.push(this.students)%0A%09%09%09this.students = 
 this
@@ -556,33 +556,32 @@
 .first()
-)
 %0A
+%09
 %09%09this.
-students
+history
  = this.
@@ -588,24 +588,23 @@
 history.
-shift
+pop
 ()%0A
+%09
 %09%09this._
@@ -612,24 +612,28 @@
 ostChange()%0A
+%09%09%7D%0A
 %09%7D,%0A%0A%09redo()
@@ -668,71 +668,156 @@
 %0A%09%09%09
-this.history = this.future%0A%09%09%09this.students = this.future.shift
+console.log('redoing...')%0A%09%09%09this.history = this.history.push(this.students)%0A%09%09%09this.students = this.future.first()%0A%09%09%09this.future = this.future.pop
 ()%0A%09

Fix undo/redo in studentStore