import { ActionHandleStrategy } from '../../../dto/action-handle-strategies/action-handle-strategy.abstract';
import { InsertChildrenAfterAction } from '../../../dto/actions/insert-children-after-block';
import { InsertChildrenBeforeAction } from '../../../dto/actions/insert-children-before-block';
import { UpdateCursorPositionAction } from '../../../dto/actions/update-cursor-position-action';
import { InternalAnnotationTypeEnum } from '../../../dto/annotations/annotation.abstract';
import { RTETextBlock } from '../../../dto/blocks/text-block';
import { RTETextNode } from '../../../dto/nodes/text-node';
/**
 * Strategy to handle the paste content into function block.
 */
export class PastePlainTextStrategy extends ActionHandleStrategy {
  /**
   * @inheritDoc
   */
  handleAction(action, target) {
    const { blocksToBeInserted, startNode, startOffset } = action;
    if (startNode instanceof RTETextNode) {
      const textNodes = blocksToBeInserted.flatMap((block) => {
        if (block instanceof RTETextBlock) {
          this.copyLinkGroupAnnotations(target.annotationMap, block.annotationMap);
          return block.children;
        }
        return [];
      });
      if (textNodes.length > 0) {
        if (startOffset > 0) {
          target.apply(new InsertChildrenAfterAction(startNode, ...textNodes));
        }
        else {
          target.apply(new InsertChildrenBeforeAction(startNode, ...textNodes));
        }
        this.focusToNextLine(textNodes[textNodes.length - 1], textNodes[textNodes.length - 1].getRangeEndOffset());
      }
    }
  }
  /**
   * Focus to next paragraph.
   *
   * @param {RTETextNode} node - The text node need to focus.
   * @param {number} startOffset - The offset need to focus.
   */
  focusToNextLine(node, startOffset) {
    const root = this.getRootContent(node);
    if (root) {
      root.apply(new UpdateCursorPositionAction(node, startOffset));
    }
  }
  /**
   * Copy link group annotations from copied block to target block.
   *
   * @param {BlockAnnotations} blockAnnotationMap - The target block annotation map.
   * @param {BlockAnnotations} copiedAnnotationMap - The copied block annotation map.
   */
  copyLinkGroupAnnotations(blockAnnotationMap, copiedAnnotationMap) {
    if (copiedAnnotationMap && copiedAnnotationMap.has(InternalAnnotationTypeEnum.LINK_GROUP)) {
      const copiedLinkGroupAnnotation = copiedAnnotationMap.get(InternalAnnotationTypeEnum.LINK_GROUP);
      if (!blockAnnotationMap.has(InternalAnnotationTypeEnum.LINK_GROUP)) {
        blockAnnotationMap.set(InternalAnnotationTypeEnum.LINK_GROUP, copiedAnnotationMap.get(InternalAnnotationTypeEnum.LINK_GROUP));
      }
      else {
        copiedLinkGroupAnnotation.linkGroups.forEach((nodes, groupKey) => {
          const existingAnnotation = blockAnnotationMap.get(InternalAnnotationTypeEnum.LINK_GROUP);
          existingAnnotation.linkGroups.set(groupKey, nodes);
        });
      }
    }
  }
}
