import { Command } from 'substance'

class BasicCollectionCommand extends Command {
  getCommandState (params, context) {
    return { disabled: this.isDisabled(params, context) }
  }

  isDisabled (params, context) {
    return params.selection.getType() !== 'property'
  }

  _getCardModel (params, context) {
    const nodeId = params.selection.getNodeId()
    const doc = context.editorSession.getDocument()
    const node = doc.get(nodeId)
    return this._getCardModelForNode(node, context)
  }

  _getCollectionForNode (params, context) {
    const nodeId = params.selection.getNodeId()
    const doc = params.editorSession.getDocument()
    const node = doc.get(nodeId)
    const collection = this._getParentCollection(node, context)
    return collection
  }

  _getCardModelForNode (node, context) {
    let parent = node.getParent()
    let collection = context.api.getModel(parent.type)
    let model
    if (!collection) {
      // NOTE: we are bubling up until we reach
      // a child model of registered collection
      model = this._getCardModelForNode(parent, context)
    } else {
      model = context.api.getModelById(node.id)
    }
    return model
  }

  _getParentCollection (node, context) {
    const parent = node.getParent()
    let collection = context.api.getModel(parent.type)
    if (!collection) {
      // NOTE: we are bubling up until we found a registered collection
      collection = this._getParentCollection(parent, context)
    }
    return collection
  }
}

export class RemoveCollectionItemCommand extends BasicCollectionCommand {
  execute (params, context) {
    const model = this._getCardModel(params, context)
    const collection = this._getCollectionForNode(params, context)
    collection.removeItem(model)
  }

  isDisabled (params, context) {
    return params.selection.getType() !== 'property' || !this._getCollectionForNode(params, context).isRemovable
  }
}

export class MoveCollectionItemCommand extends BasicCollectionCommand {
  execute (params, context) {
    const direction = this.config.direction
    const model = this._getCardModel(params, context)
    const collection = this._getCollectionForNode(params, context)
    if (direction === 'up') {
      collection.moveUp(model)
    } else if (direction === 'down') {
      collection.moveDown(model)
    }
  }

  isDisabled (params, context) {
    if (params.selection.getType() !== 'property') return true
    const collection = this._getCollectionForNode(params, context)
    if (!collection.isMovable) return true
    const direction = this.config.direction
    const model = this._getCardModel(params, context)
    const pos = collection._getModelPosition(model)
    if (direction === 'up' && pos === 0) return true
    if (direction === 'down' && pos === collection.length - 1) return true
    return false
  }
}

@@ -1248,38 +1248,57 @@
 arent()%0A    
-let collection
+if (!parent) return%0A    let model
  = context.a
@@ -1304,32 +1304,36 @@
 api.getModel
+ById
 (parent.
 type)%0A    if
@@ -1316,28 +1316,26 @@
 ById(parent.
-type
+id
 )%0A    if (!c
@@ -1325,33 +1325,41 @@
 nt.id)%0A    if (!
-c
+model.isC
 ollection) %7B%0A   
@@ -1433,26 +1433,21 @@
 n%0A      
-collection
+model
  = this.
@@ -1497,34 +1497,29 @@
 %0A    return 
-collection
+model
 %0A  %7D%0A%7D%0A%0Aexpo
@@ -1806,39 +1806,36 @@
  context) %7B%0A    
-return 
+if (
 params.selection
@@ -1863,13 +1863,45 @@
 rty'
- %7C%7C !
+) return true%0A    const collection = 
 this
@@ -1943,19 +1943,84 @@
 ext)
-.isRemovabl
+%0A    if (!collection %7C%7C !collection.isRemovable) return true%0A    return fals
 e%0A  
@@ -2617,16 +2617,31 @@
 llection
+ %7C%7C !collection
 .isMovab

Change model retrievement way.