// Disable no-re-export rule for entry point files
/* eslint-disable @atlaskit/editor/no-re-export */

import { AllSelection, NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
import { CellSelection } from '@atlaskit/editor-tables';
import { selectedRect } from '@atlaskit/editor-tables/utils';
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../analytics';
export { RelativeSelectionPos } from './types';
export { GapCursorSelection, Side, JSON_ID, GapBookmark } from './gap-cursor/selection';
export { setSelectionTopLevelBlocks, setGapCursorAtPos } from './gap-cursor/actions';
export { isIgnored } from './gap-cursor/utils/is-ignored';
export { isValidTargetNode } from './gap-cursor/utils/is-valid-target-node';
export { setGapCursorSelection } from './gap-cursor/utils/setGapCursorSelection';
export { hideCaretModifier, gapCursorStyles } from './gap-cursor/styles';
export { atTheBeginningOfBlock, atTheBeginningOfDoc, atTheEndOfBlock, atTheEndOfDoc, deleteSelectedRange, endPositionOfParent, expandSelectionBounds, expandSelectionToBlockRange, expandToBlockRange, getSourceNodesFromSelectionRange, isMultiBlockRange, isMultiBlockSelection, isSelectionAtEndOfNode, isSelectionAtStartOfNode, selectionIsAtTheBeginningOfBlock, startPositionOfParent } from './utils';
export function getNodeSelectionAnalyticsPayload(selection) {
  if (selection instanceof NodeSelection) {
    return {
      action: ACTION.SELECTED,
      actionSubject: ACTION_SUBJECT.DOCUMENT,
      actionSubjectId: ACTION_SUBJECT_ID.NODE,
      eventType: EVENT_TYPE.TRACK,
      attributes: {
        node: selection.node.type.name
      }
    };
  }
}
export function getAllSelectionAnalyticsPayload(selection) {
  if (selection instanceof AllSelection) {
    return {
      action: ACTION.SELECTED,
      actionSubject: ACTION_SUBJECT.DOCUMENT,
      actionSubjectId: ACTION_SUBJECT_ID.ALL,
      eventType: EVENT_TYPE.TRACK
    };
  }
}
export function getCellSelectionAnalyticsPayload(state) {
  if (state.selection instanceof CellSelection) {
    var rect = selectedRect(state);
    var selectedCells = rect.map.cellsInRect(rect).length;
    var totalCells = rect.map.map.length;
    return {
      action: ACTION.SELECTED,
      actionSubject: ACTION_SUBJECT.DOCUMENT,
      actionSubjectId: ACTION_SUBJECT_ID.CELL,
      eventType: EVENT_TYPE.TRACK,
      attributes: {
        selectedCells: selectedCells,
        totalCells: totalCells
      }
    };
  }
}
export function getRangeSelectionAnalyticsPayload(selection, doc) {
  if (selection instanceof TextSelection && selection.from !== selection.to) {
    var from = selection.from,
      to = selection.to,
      anchor = selection.anchor,
      head = selection.head;
    var nodes = [];
    doc.nodesBetween(from, to, function (node, pos) {
      // We want to send top-level nodes only, ie.the nodes that would have the selection styling
      // We allow text nodes that are not fully covered as they are a special case
      if (node.isText || pos >= from && pos + node.nodeSize <= to) {
        nodes.push(node.type.name);
        return false;
      }
    });
    return {
      action: ACTION.SELECTED,
      actionSubject: ACTION_SUBJECT.DOCUMENT,
      actionSubjectId: ACTION_SUBJECT_ID.RANGE,
      eventType: EVENT_TYPE.TRACK,
      attributes: {
        from: anchor,
        to: head,
        nodes: nodes
      }
    };
  }
}

/**
 * Insert content, delete a range and create a new selection
 * This function automatically handles the mapping of positions for insertion and deletion.
 * The new selection is handled as a function since it may not always be necessary to resolve a position to the transactions mapping
 *
 * @param getSelectionResolvedPos get the resolved position to create a new selection
 * @param insertions content to insert at the specified position
 * @param deletions the ranges to delete
 */

export var selectNode = function selectNode(pos) {
  return function (state, dispatch) {
    if (dispatch) {
      dispatch(state.tr.setSelection(new NodeSelection(state.doc.resolve(pos))));
    }
    return true;
  };
};
export function createSelectionClickHandler(nodes, isValidTarget, options) {
  return function handleClickOn(view, _pos, node, nodePos, event, direct) {
    if (options.useLongPressSelection) {
      return false;
    }
    if (direct && nodes.indexOf(node.type.name) !== -1) {
      var target = event.target;
      if (target instanceof HTMLElement && isValidTarget(target)) {
        var selectionPos = options.getNodeSelectionPos ? options.getNodeSelectionPos(view.state, nodePos) : nodePos;
        selectNode(selectionPos)(view.state, view.dispatch);
        return true;
      }
    }
    return false;
  };
}