import Immutable from 'immutable';
import {Store} from 'flummox';


const TaskList = Immutable.Record({
    id: undefined,
    name: '',
    isEditing: false,
    tasks: Immutable.List()
});


const Task = Immutable.Record({
    id: undefined,
    text: '',
    taskListId: undefined
});


export default class TaskListStore extends Store {
    constructor(flux) {
        super();

        const actions = flux.getActions('taskLists');

        this.register(actions.getBoard, this.onNewBoard);
        this.register(actions.createTaskList, this.onNewTaskList);
        this.register(actions.createTask, this.onNewTask);
        this.register(actions.moveTask, this.onTaskMoved);
        this.register(actions.deleteTask, this.onTaskRemoved);
        this.register(actions.deleteTaskList, this.onTaskListRemoved);
        this.register(actions.updateTaskListName, this.onUpdateTaskListName);
        this.register(actions.toggleTaskListEditMode, this.onToggleTaskListEditMode);

        this.taskListMap = Immutable.OrderedMap();

        this.state = {
            taskLists: Immutable.List()
        };

    }

    onNewBoard(taskLists) {
        this.taskListMap = this.taskListMap.clear();
        taskLists.forEach((result) => {

            let tasks = Immutable.List();

            result.tasks.forEach((task) => {
                tasks = tasks.push(new Task({
                    id: task.id,
                    text: task.text,
                    taskListId: task.taskListId
                }));
            });

            const rec = new TaskList({
                id: result.id,
                name: result.name,
                tasks: tasks
            });

            this.taskListMap = this.taskListMap.set(result.id, new TaskList({
                id: result.id,
                name: result.name,
                tasks: tasks
            }));

        }.bind(this));
        this.dispatch();
    }

    onNewTaskList(list) {
        this.updateList(new TaskList(list).set("tasks", Immutable.List()));
        this.dispatch();
    }

    onUpdateTaskListName(payload) {
        const {list, name} = payload;
        this.updateList(this.getList(list.id).set("name", name));
        this.dispatch();
    }

    onToggleTaskListEditMode(list) {
        const rec = this.getList(list.id);
        this.updateList(rec.set("isEditing", !rec.isEditing));
        this.dispatch();
    }

    onNewTask(payload) {
        const {list, task} = payload;
        this.updateList(this.addTask(this.getList(list.id), new Task(task)));
        this.dispatch();
    }

    onTaskListRemoved(list) {
        this.taskListMap = this.taskListMap.delete(list.id);
        this.dispatch();
    }

    onTaskRemoved(task) {
        this.updateList(this.removeTask(task));
        this.dispatch();
    }

    onTaskMoved(payload) {
        const {list, task} = payload;

        this.updateList(this.removeTask(task));
        const newTaskRec = new Task(task).set("taskListId", list.id);
        this.updateList(this.addTask(this.getList(list.id), newTaskRec));

        this.dispatch();
    }

    updateList(newList) {
        this.taskListMap = this.taskListMap.set(newList.id, newList);
    }

    getList(id) {
        return this.taskListMap.get(id);
    }

    addTask(list, task) {
        return list.set("tasks", list.tasks.unshift(task));
    }

    removeTask(task) {
        const list = this.getList(task.taskListId);
        const tasks = list.tasks.filterNot((t) => t.id === task.id);
        return list.set("tasks", tasks);
     }

    dispatch() {
        this.setState({ taskLists:  this.taskListMap.toList() });
    }

}

@@ -1365,145 +1365,12 @@
 ask(
-%7B%0A                    id: task.id,%0A                    text: task.text,%0A                    taskListId: task.taskListId%0A                %7D
+task
 ));%0A
@@ -1404,19 +1404,24 @@
   const 
-rec
+taskList
  = new T
@@ -1432,122 +1432,37 @@
 ist(
-%7B%0A                id: result.id,%0A                name: result.name,%0A                
+result).set(%22
 tasks
-:
+%22,
  tasks
-%0A            %7D
 );%0A
-%0A
     
@@ -1478,178 +1478,25 @@
 his.
-taskListMap = this.taskListMap.set(result.id, new TaskList(%7B%0A                id: result.id,%0A                name: result.name,%0A                tasks: tasks%0A            %7D)
+saveList(taskList
 );%0A%0A
@@ -1585,29 +1585,27 @@
        this.
-updat
+sav
 eList(new Ta
@@ -1761,37 +1761,35 @@
 d;%0A        this.
-updat
+sav
 eList(this.getLi
@@ -1941,29 +1941,27 @@
        this.
-updat
+sav
 eList(rec.se
@@ -2093,37 +2093,35 @@
 d;%0A        this.
-updat
+sav
 eList(this.addTa
@@ -2350,37 +2350,35 @@
  %7B%0A        this.
-updat
+sav
 eList(this.remov
@@ -2494,37 +2494,35 @@
 ;%0A%0A        this.
-updat
+sav
 eList(this.remov
@@ -2618,21 +2618,19 @@
    this.
-updat
+sav
 eList(th
@@ -2714,21 +2714,19 @@
  %7D%0A%0A    
-updat
+sav
 eList(ne

Tidy up