import { generateUUID } from '../../../../../../utils/misc';
import { RTEListBlock } from '../../../../dto/blocks/list-block';
import { RTEListItemBlock } from '../../../../dto/blocks/list-item-block';
import { RTETextNode } from '../../../../dto/nodes/text-node';
import htmlElementToAnnotationGenerator from './annotation-handler/html-element-to-annotation-generator';
import { BlockToRTEBlockStrategyAbstract } from './block-to-rte-block-strategy.abstract';
/** Transform li element to list item block DTO */
export class LiToRTEListItemBlockStrategy extends BlockToRTEBlockStrategyAbstract {
  /**
   * Can be handled.
   *
   * @param {HTMLElement[]} elementsArray - Current elements.
   * @param {number} currentIndex - Current element index.
   * @returns {number} - can be handled element count.
   */
  canHandle(elementsArray, currentIndex) {
    const parent = elementsArray[currentIndex].parentElement;
    if (!['UL', 'OL'].includes(parent.nodeName) &&
      elementsArray.some((element) => element.nodeName === 'LI')) {
      let count = 0;
      for (let i = currentIndex; i < elementsArray.length; i++) {
        if (elementsArray[i].nodeName === 'LI') {
          count++;
        }
        else {
          break;
        }
      }
      return count;
    }
    return elementsArray[currentIndex].tagName === 'LI' ? 1 : 0;
  }
  /**
   * Parse to a list item block.
   *
   * @param {HTMLElement[]} elementsArray - Current elements.
   * @param {VegaRTETransformOptions} [options] - Options for transformation.
   * @returns {Nullable<RTEContentBlock>} - List item block.
   */
  handle(elementsArray, options) {
    const firstElement = elementsArray[0];
    const parent = firstElement.parentElement;
    if (!['UL', 'OL'].includes(parent.nodeName)) {
      return this.generateWithListBlock(elementsArray, options);
    }
    return RTEListItemBlock.from(this.generateListItemBlockDTO(firstElement, options), options);
  }
  /**
   * Append child list blocks to current list item block.
   *
   * @param {RTEListBlock} currentBlock - Current list item block.
   * @param {RTEListItemBlock[]} childBlocks - Current list blocks.
   */
  appendChildBlocks(currentBlock, childBlocks) {
    currentBlock.nestList = childBlocks.filter((block) => ['bullet-list', 'number-list'].includes(block.type));
  }
  /**
   * Should continue process to child elements.
   *
   * @returns {boolean} - boolean.
   */
  shouldProceedToElementChildren() {
    return true;
  }
  /**
   * Generate list block from a list of HTML elements.
   *
   * @param {HTMLElement[]} elements - List of HTML elements to convert.
   * @param {VegaRTETransformOptions} options - Options for transformation.
   * @returns {RTEListBlock} - List block DTO.
   */
  generateWithListBlock(elements, options) {
    return RTEListBlock.from({
      id: generateUUID(),
      type: 'bullet-list',
      blocks: elements.map((item) => {
        return this.generateListItemBlockDTO(item, options);
      }),
    }, options);
  }
  /**
   * Generate list item block DTO from an HTML element.
   *
   * @param {HTMLElement} element - HTML element to convert.
   * @param {VegaRTETransformOptions} options - Options for transformation.
   * @returns {VegaRTEListItemBlock} - List item block DTO.
   */
  generateListItemBlockDTO(element, options) {
    return {
      id: generateUUID(),
      type: 'list-item',
      annotations: htmlElementToAnnotationGenerator.generate(RTEListItemBlock, element, options),
      nodes: this.generateChildNodes(Array.from(element.childNodes.length ? element.childNodes : [element]).filter((item) => {
        return !['UL', 'OL'].includes(item.nodeName);
      }), htmlElementToAnnotationGenerator.generate(RTETextNode, element, Object.assign(Object.assign({}, options), { skipCustomAnnotations: true })), options),
    };
  }
}
