export default Controller

/**
* Takes a model and view and acts as the controller between them
*
* @constructor
* @param {object} model The model instance
* @param {object} view The view instance
*/
function Controller(model, view) {
  var that = this
  that.model = model
  that.view = view

  that.view.bind('newTodo', function(title) {
    that.addItem(title)
  })

  that.view.bind('itemEdit', function(item) {
    that.editItem(item.id)
  })

  that.view.bind('itemEditDone', function(item) {
    that.editItemSave(item.id, item.title)
  })

  that.view.bind('itemEditCancel', function(item) {
    that.editItemCancel(item.id)
  })

  that.view.bind('itemRemove', function(item) {
    that.removeItem(item.id)
  })

  that.view.bind('itemToggle', function(item) {
    that.toggleComplete(item.id, item.completed)
  })

  that.view.bind('removeCompleted', function() {
    that.removeCompletedItems()
  })

  that.view.bind('toggleAll', function(status) {
    that.toggleAll(status.completed)
  })
}

/**
* Loads and initialises the view
*
* @param {string} '' | 'active' | 'completed'
*/
Controller.prototype.setView = function(locationHash) {
  var route = locationHash.split('/')[1]
  var page = route || ''
  this._updateFilterState(page)
}

/**
* An event to fire on load. Will get all items and display them in the
* todo-list
*/
Controller.prototype.showAll = function() {
  var that = this
  that.model.read(function(data) {
    that.view.render('showEntries', data)
  })
}

/**
* Renders all active tasks
*/
Controller.prototype.showActive = function() {
  var that = this
  that.model.read({completed: false}, function(data) {
    that.view.render('showEntries', data)
  })
}

/**
* Renders all completed tasks
*/
Controller.prototype.showCompleted = function() {
  var that = this
  that.model.read({completed: true}, function(data) {
    that.view.render('showEntries', data)
  })
}

/**
* An event to fire whenever you want to add an item. Simply pass in the event
* object and it'll handle the DOM insertion and saving of the new item.
*/
Controller.prototype.addItem = function(title) {
  var that = this

  if (title.trim() === '') {
    return
  }

  that.model.create(title, function() {
    that.view.render('clearNewTodo')
    that._filter(true)
  })
}

/*
* Triggers the item editing mode.
*/
Controller.prototype.editItem = function(id) {
  var that = this
  that.model.read(id, function(data) {
    that.view.render('editItem', {id, title: data[0].title})
  })
}

/*
* Finishes the item editing mode successfully.
*/
Controller.prototype.editItemSave = function(id, title) {
  var that = this
  if (title.trim()) {
    that.model.update(id, {title}, function() {
      that.view.render('editItemDone', {id, title})
    })
  } else {
    that.removeItem(id)
  }
}

/*
* Cancels the item editing mode.
*/
Controller.prototype.editItemCancel = function(id) {
  var that = this
  that.model.read(id, function(data) {
    that.view.render('editItemDone', {id, title: data[0].title})
  })
}

/**
* By giving it an ID it'll find the DOM element matching that ID,
* remove it from the DOM and also remove it from storage.
*
* @param {number} id The ID of the item to remove from the DOM and
* storage
*/
Controller.prototype.removeItem = function(id) {
  var that = this
  that.model.remove(id, function() {
    that.view.render('removeItem', id)
  })

  that._filter()
}

/**
* Will remove all completed items from the DOM and storage.
*/
Controller.prototype.removeCompletedItems = function() {
  var that = this
  that.model.read({completed: true}, function(data) {
    data.forEach(function(item) {
      that.removeItem(item.id)
    })
  })

  that._filter()
}

/**
* Give it an ID of a model and a checkbox and it will update the item
* in storage based on the checkbox's state.
*
* @param {number} id The ID of the element to complete or uncomplete
* @param {object} checkbox The checkbox to check the state of complete
*                          or not
* @param {boolean|undefined} silent Prevent re-filtering the todo items
*/
Controller.prototype.toggleComplete = function(id, completed, silent) {
  var that = this
  that.model.update(id, {completed}, function() {
    that.view.render('elementComplete', {
      id,
      completed,
    })
  })

  if (!silent) {
    that._filter()
  }
}

/**
* Will toggle ALL checkboxes' on/off state and completeness of models.
* Just pass in the event object.
*/
Controller.prototype.toggleAll = function(completed) {
  var that = this
  that.model.read({completed: !completed}, function(data) {
    data.forEach(function(item) {
      that.toggleComplete(item.id, completed, true)
    })
  })

  that._filter()
}

/**
* Updates the pieces of the page which change depending on the remaining
* number of todos.
*/
Controller.prototype._updateCount = function() {
  var that = this
  that.model.getCount(function(todos) {
    that.view.render('updateElementCount', todos.active)
    that.view.render('clearCompletedButton', {
      completed: todos.completed,
      visible: todos.completed > 0
    })

    that.view.render('toggleAll', {checked: todos.completed === todos.total})
    that.view.render('contentBlockVisibility', {visible: todos.total > 0})
  })
}

/**
* Re-filters the todo items, based on the active route.
* @param {boolean|undefined} force  forces a re-painting of todo items.
*/
Controller.prototype._filter = function(force) {
  var activeRoute = this._activeRoute.charAt(0).toUpperCase() + this._activeRoute.substr(1)

  // Update the elements on the page, which change with each completed todo
  this._updateCount()

  // If the last active route isn't "All", or we're switching routes, we
  // re-create the todo item elements, calling:
  //   this.show[All|Active|Completed]();
  if (force || this._lastActiveRoute !== 'All' || this._lastActiveRoute !== activeRoute) {
    this['show' + activeRoute]()
  }

  this._lastActiveRoute = activeRoute
}

/**
* Simply updates the filter nav's selected states
*/
Controller.prototype._updateFilterState = function(currentPage) {
  // Store a reference to the active route, allowing us to re-filter todo
  // items as they are marked complete or incomplete.
  currentPage = currentPage.split('?')[0]
  this._activeRoute = currentPage

  if (currentPage === '') {
    this._activeRoute = 'All'
  }

  this._filter()

  this.view.render('setFilter', currentPage)
}
