import { generateUUID } from '../../../../../utils/misc';
import { RemoveChildrenAction } from '../../actions/remove-child-action';
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 multiple blocks selection at special position strategy.
 */
export class BlockInsertLineBreakWithBlocksStrategy extends ActionHandleStrategy {
  /**
   * @inheritDoc
   */
  handleAction(action, target) {
    action.lineBreakNode = this.lineBreakMultipleBlocks(action.selectedBlocks, target);
  }
  /**
   * lineBreakMultipleBlocks
   *
   * @param {RTEBlock[]} selectedBlocks -
   * @param {RTETextBlock} target -
   * @returns {Nullable<RTETextNode>} Nullable<RTETextNode>
   */
  lineBreakMultipleBlocks(selectedBlocks, target) {
    const beforeNodes = target.children;
    const lineBreakNode = new RTETextNode(generateUUID(), '\n', target);
    const afterNodes = this.concatBlocksNodes(selectedBlocks.slice(1));
    this.mergeLineBreakNodes(beforeNodes, lineBreakNode, afterNodes, target);
    return lineBreakNode;
  }
  /**
   * Concat the child nodes of multiple RTEBlocks if both are not images.
   *
   * @param {RTEBlock[]} blocks - multiple block of content in a rich text editor, such as a paragraph, heading, image, etc.
   * @returns {RTENode[]} Array of connected block nodes
   */
  concatBlocksNodes(blocks) {
    const nodes = [];
    blocks.map((block) => {
      if (block.type !== 'image') {
        nodes.push(...block.children);
        block.parent.apply(new RemoveChildrenAction(block));
      }
    });
    return nodes;
  }
  /**
   * 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]));
  }
}
