import { RTEBlock } from './block.abstract';
import { ActionHandleStrategyRegistry } from '../action-handle-strategies/action-handle-strategy-registry';
import { ModifyContentAction, ModifyContentActionType } from '../actions/modify-content-action.abstract';
import stateEntityRenderingRegistry from '../../slimmers/controllers/state-entity-rendering-registry';
import domNodeSubjectFactory from '../../../../helpers/change-manager/subject/dom-node-subject/dom-node-subject-factory';
import { VegaInternalRichTextEditorFlushChanges } from '../../../../helpers/event-manager/event-id/vega-internal-event-id';
import changeManager from '../../../../helpers/change-manager/change-manager';
import { CodeBlockRemoveSelfStrategy } from '../action-handle-strategies/modify-content-strategies/code-block-remove-self-strategy';
import { SwitchOutFromCodeBlockStrategy } from '../action-handle-strategies/modify-content-strategies/switch-out-from-code-block-strategy';
import { RTECodeBlockNode } from '../nodes/code-block-node';
import { InternalAnnotationTypeEnum } from '../annotations/annotation.abstract';
import { CodeBlockInsertImageStrategy } from '../action-handle-strategies/modify-content-strategies/code-block-insert-image-strategy';
import { CodeLanguage } from '../../../vega-code-block/types';
import { RemoveChildrenStrategy } from '../action-handle-strategies/modify-content-strategies/remove-children-strategy';
import { CustomStyleAnnotation } from '../annotations/custom-style-annotation';
import { CodeBlockFilterStylesStrategy } from '../filter-styles-strategies/code-block/code-block-filter-styles-strategy';
/**
 * The code block DTO class.
 */
export class RTECodeBlock extends RTEBlock {
  constructor(id, content, language) {
    super(id);
    this.type = 'code-block';
    this.annotationMap = new Map([CustomStyleAnnotation.from(CodeBlockFilterStylesStrategy.STYLES)]);
    this.children = [new RTECodeBlockNode(`${id}-1`, content, language, this)];
  }
  /**
   * Converts a VegaRTECodeBlock into an RTECodeBlock.
   *
   * @param {VegaRTECodeBlock} block - The block object
   * @returns {RTECodeBlock} A RTECodeBlock class
   */
  static from(block) {
    return new RTECodeBlock(block.id, block.content, block.language);
  }
  /**
   * @inheritDoc
   */
  toJSON() {
    const { language, text } = this.children[0];
    return {
      id: this.id,
      type: 'code-block',
      content: text,
      language,
    };
  }
  /**
   * @inheritDoc
   */
  toHtml(options) {
    const { language = CodeLanguage['Plain Text'] } = this.children[0];
    const attrStr = super.generateAttributeString(options);
    return `<pre data-language="${language}"${attrStr}>${this.children.map((node) => node.toHtml(options))}</pre>`;
  }
  /**
   * @inheritDoc
   */
  clone(parent) {
    const cloneCodeBlock = RTECodeBlock.from(this.toJSON());
    cloneCodeBlock.parent = parent;
    return cloneCodeBlock;
  }
  /**
   * Apply action to block
   *
   * @param {ModifyContentAction} action - modify content action.
   */
  apply(action) {
    if (action instanceof ModifyContentAction) {
      ActionHandleStrategyRegistry.executeTheStrategy(action, this);
    }
    if (action.isFlushable) {
      const domNode = stateEntityRenderingRegistry.getDOMByEntity(this);
      if (domNode) {
        const nodeSubject = domNodeSubjectFactory.getSubjectFromParentNodeByEventId(domNode, VegaInternalRichTextEditorFlushChanges);
        if (nodeSubject) {
          changeManager.notify(nodeSubject, {});
        }
      }
    }
  }
  /**
   * @inheritDoc
   */
  isNotEmpty() {
    return !!this.children.length;
  }
  /**
   * @inheritDoc
   */
  getLastNode() {
    return this.children[0];
  }
  /**
   * The code block is selected or not.
   *
   * @returns {boolean} - The boolean result.
   */
  isSelected() {
    return this.children[0].annotationMap.has(InternalAnnotationTypeEnum.SELECTION_RANGE);
  }
}
(() => {
  ActionHandleStrategyRegistry.register(ModifyContentActionType.DELETE_CODE_BLOCK, RTECodeBlock.name, new CodeBlockRemoveSelfStrategy());
  ActionHandleStrategyRegistry.register(ModifyContentActionType.DELETE_CHILDREN, RTECodeBlock.name, new RemoveChildrenStrategy());
  ActionHandleStrategyRegistry.register(ModifyContentActionType.SWITCH_OUT_FROM_CODE_BLOCK, RTECodeBlock.name, new SwitchOutFromCodeBlockStrategy());
  ActionHandleStrategyRegistry.register(ModifyContentActionType.INSERT_IMAGE_TO_BLOCK, RTECodeBlock.name, new CodeBlockInsertImageStrategy());
})();
RTECodeBlock.CODE_BLOCK_PLACEHOLDER_CLASS_NAME = 'code-block-placeholder-element';
