import union from 'lodash/union'
import { assertSlot } from './helpers'

export const mutations = {
  /**
   * Select nodes
   * @param {Object} state
   * @param {Object} pl payload
   * @param {number}   pl.slotId dataset slot
   * @param {number[]} pl.nodeIds to select
   */
  SELECT_NODES(state, pl) {
    assertSlot(state, pl.slotId)
    state[pl.slotId].vis.selectedNodes = union(state[pl.slotId].vis.selectedNodes, pl.nodeIds)
  },

  /**
   * Deselect nodes
   * @param {Object} state
   * @param {Object} pl payload
   * @param {number}   pl.slotId dataset slot
   * @param {number[]} pl.nodeIds to deselect
   */
  DESELECT_NODES(state, pl) {
    assertSlot(state, pl.slotId)
    state[pl.slotId].vis.selectedNodes = state[pl.slotId].vis.selectedNodes.filter(
      uuid => !pl.nodeIds.includes(uuid) || pl.nodeId === uuid
    )
  },

  /**
   * Deselect all nodes
   * @param {Object} state
   * @param {Object} pl payload
   * @param {number}   pl.slotId dataset slot
   */
  DESELECT_ALL_NODES(state, pl) {
    state[pl.slotId].vis.selectedNodes = []
  },

  FOCUS_NODES(state, pl) {
    assertSlot(state, pl.slotId)
    state[pl.slotId].vis.focusedNodes = union(state[pl.slotId].vis.focusedNodes, pl.nodeIds)
  },

  UNFOCUS_NODES(state, pl) {
    assertSlot(state, pl.slotId)
    state[pl.slotId].vis.focusedNodes = state[pl.slotId].vis.focusedNodes.filter(
      id => !pl.nodeIds.includes(id)
    )
  }
}

export const actions = {
  // selections
  selectNodes({ commit }, pl) {
    commit('SELECT_NODES', pl)
  },

  deselectNodes({ commit }, pl) {
    commit('DESELECT_NODES', pl)
  },

  deselectAllNodes({ commit }, pl) {
    commit('DESELECT_ALL_NODES', pl)
  },

  // permanent focus
  focusNodes({ commit }, pl) {
    commit('FOCUS_NODES', pl)
  },

  unfocusNodes({ commit }, pl) {
    commit('UNFOCUS_NODES', pl)
  }
}

export const getters = {
  getSelectedNodes: state => slotId => state[slotId].vis.selectedNodes,
  isNodeSelected: state => (slotId, nodeId) => state[slotId].vis.selectedNodes.includes(nodeId),

  getFocusedNodes: state => slotId => state[slotId].vis.focusedNodes,
  isNodeFocused: state => (slotId, nodeId) => state[slotId].vis.focusedNodes.includes(nodeId)
}
