import { generateUUID } from '../../../../../utils/misc';
import { ReplaceChildNodesAction } from '../../actions/replace-child-nodes-action';
import { RTETextNode } from '../../nodes/text-node';
import { ActionHandleStrategy } from '../action-handle-strategy.abstract';
/**
 * Insert a line break node into current text block at special position strategy.
 */
export class BlockInsertLineBreakStrategy extends ActionHandleStrategy {
  /**
   * @inheritDoc
   */
  handleAction(action, target) {
    action.lineBreakNode = this.lineBreakSingleBlock(action.startContainerNode, action.startOffset, target);
  }
  /**
   * lineBreakSingleBlock
   *
   * @param {RTETextNode} splitNode -
   * @param {number} startOffsetOfNode -
   * @param {RTETextBlock} target -
   * @returns {Nullable<RTETextNode>} Nullable<RTETextNode>
   */
  lineBreakSingleBlock(splitNode, startOffsetOfNode, target) {
    if (splitNode) {
      const lineBreakNode = new RTETextNode(generateUUID(), '\n', target);
      const beforeText = splitNode.text.slice(0, startOffsetOfNode);
      const afterText = splitNode.text.slice(startOffsetOfNode);
      const nodesSplitIndex = target.children.indexOf(splitNode);
      if (nodesSplitIndex > -1) {
        const beforeNodes = target.children.slice(0, nodesSplitIndex);
        const afterNodes = target.children.slice(nodesSplitIndex + 1);
        if (beforeText) {
          beforeNodes.push(splitNode.cloneWithText(beforeText));
        }
        if (afterText) {
          afterNodes.unshift(splitNode.cloneWithText(afterText));
        }
        this.mergeLineBreakNodes(beforeNodes, lineBreakNode, afterNodes, target);
      }
      return lineBreakNode;
    }
  }
  /**
   * mergeLineBreakNodes
   *
   * @param {RTENode[]} beforeNodes -
   * @param {RTETextNode} lineBreakNode -
   * @param {RTENode[]} afterNodes -
   * @param {RTETextBlock} target -
   */
  mergeLineBreakNodes(beforeNodes, lineBreakNode, afterNodes, target) {
    if (afterNodes.length === 0 || (afterNodes[0] && afterNodes[0].text === '')) {
      afterNodes.push(new RTETextNode(generateUUID(), '\n', target, beforeNodes[beforeNodes.length - 1] && beforeNodes[beforeNodes.length - 1].annotationMap));
    }
    target.apply(new ReplaceChildNodesAction([...beforeNodes, lineBreakNode, ...afterNodes]));
  }
}
