import { RTEBlock } from './block.abstract';
import { RTEListItemBlock } from './list-item-block';
import { ModifyContentActionType } from '../actions/modify-content-action.abstract';
import { ActionHandleStrategyRegistry } from '../action-handle-strategies/action-handle-strategy-registry';
import { ListTransformToListStrategy } from '../action-handle-strategies/modify-content-strategies/list-transform-to-list-strategy';
import { ListTransformToParagraphStrategy } from '../action-handle-strategies/modify-content-strategies/list-transform-to-paragraph-strategy';
import { ListInsertImageStrategy } from '../action-handle-strategies/modify-content-strategies/list-insert-image-strategy';
import { BlockAnnotationTypeEnum } from '../annotations/block-annotation.abstract';
import { ListAnnotation } from '../annotations/list-annotation';
import { isNonNullable } from '../../../../types/type-guard';
import { CustomAttributeAnnotation } from '../annotations/custom-attribute-annotation';
import { CustomClassAnnotation } from '../annotations/custom-class-annotation';
import { CustomStyleAnnotation } from '../annotations/custom-style-annotation';
/**
 * List block
 */
export class RTEListBlock extends RTEBlock {
  constructor(id, type, options) {
    super(id);
    this.type = 'bullet-list';
    this.children = [];
    this.type = type;
    const { autoMatchFormat } = options || { autoMatchFormat: true };
    if (autoMatchFormat) {
      this.annotationMap.set(BlockAnnotationTypeEnum.LIST, new ListAnnotation());
    }
  }
  /**
   * Converts a VegaRTEListBlock object to an RTEListBlock
   *
   * @param {VegaRTEListBlock} block - Converts a `VegaRTEListBlock` object into an `RTEListBlock`.
   * @param {VegaRTETransformOptions} options - Optional transformation options.
   * @returns {RTEListBlock} Return an instance of `RTEListBlock`
   */
  static from(block, options = { autoMatchFormat: true }) {
    const listBlock = new RTEListBlock(block.id, block.type, options);
    const { annotations } = block;
    if (annotations) {
      Object.entries(annotations).forEach(([type, value]) => {
        const item = this.createAnnotationEntity(type, value);
        if (isNonNullable(item)) {
          listBlock.annotationMap.set(...item);
        }
      });
    }
    listBlock.children = block.blocks.map((item) => {
      const listItemBlock = RTEListItemBlock.from(item, options);
      listItemBlock.parent = listBlock;
      return listItemBlock;
    });
    return listBlock;
  }
  /**
   * The function `createAnnotationEntity` creates a block annotation entity based on the provided type
   * and value.
   *
   * @param {keyof VegaRTEBlockAnnotations} type - The `type` parameter is a key of the `VegaRTEBlockAnnotations` enum, which specifies
   * the type of annotation entity to create.
   * @param {unknown} value - The `value` parameter in the `createAnnotationEntity` function is the value
   * that will be used to create the annotation entity. It can be of any type depending on the specific
   * annotation being created.
   * @returns {Nullable<BlockAnnotationsEntity>} The `createAnnotationEntity` function returns a nullable tuple containing a
   * `BlockAnnotationTypeEnum` and a `BlockAnnotation` object.
   */
  static createAnnotationEntity(type, value) {
    switch (type) {
      case 'customAttribute':
        return CustomAttributeAnnotation.from(value);
      case 'customClass':
        return CustomClassAnnotation.from(value);
      case 'customStyle':
        return CustomStyleAnnotation.from(value);
    }
  }
  /**
   * @inheritDoc
   */
  toJSON() {
    return Object.assign(Object.assign({}, super.toJSON()), { id: this.id, type: this.type, blocks: this.children.map((block) => block.toJSON()) });
  }
  /**
   * @inheritDoc
   */
  toHtml(options) {
    const BlockTag = this.getBlockTag();
    const attrStr = super.generateAttributeString(options);
    return [
      `<${BlockTag}${attrStr}>`,
      this.children.map((block) => block.toHtml(options)).join(''),
      `</${BlockTag}>`,
    ].join('');
  }
  /**
   * @inheritDoc
   */
  isNotEmpty() {
    return this.children.length > 0;
  }
  /**
   * @inheritDoc
   */
  getLastNode() {
    return this.children[this.children.length - 1].getLastNode();
  }
  /**
   * @inheritDoc
   */
  clone(parent) {
    const clonedListBlock = new RTEListBlock(this.id, this.type);
    clonedListBlock.children = this.children.map((item) => item.clone(clonedListBlock));
    clonedListBlock.annotationMap = super.cloneAnnotations();
    clonedListBlock.parent = parent;
    return clonedListBlock;
  }
  /**
   * Returns the block tag based on the type of the list block.
   *
   * @returns {RTEListBlockTagType} - The block tag for the list block, either 'ol' or 'ul'.
   */
  getBlockTag() {
    return this.type === 'number-list' ? 'ol' : 'ul';
  }
}
(() => {
  ActionHandleStrategyRegistry.register(ModifyContentActionType.TRANSFORM_LIST_BLOCK, RTEListBlock.name, new ListTransformToListStrategy());
  ActionHandleStrategyRegistry.register(ModifyContentActionType.TRANSFORM_PARAGRAPH_BLOCK, RTEListBlock.name, new ListTransformToParagraphStrategy());
  ActionHandleStrategyRegistry.register(ModifyContentActionType.INSERT_IMAGE_TO_BLOCK, RTEListBlock.name, new ListInsertImageStrategy());
})();
