import { AutoRunWhenReRenderTaskQueueSlimmer } from '../../../../helpers/slimmers/auto-run-when-re-render-task-queue-slimmer.abstract';
import stateEntityRenderingRegistry from './state-entity-rendering-registry';
/**
 * The rich text internal code block selection controller.
 */
export class InternalCodeBlockSelectionController extends AutoRunWhenReRenderTaskQueueSlimmer {
  constructor() {
    super(1);
    this.focusNodeOffset = 0;
    /**
     * The method invoke after the component re-render.
     */
    this.doTask = async () => {
      await this.focusTheCodeBlock(this.shouldFocusNode);
    };
  }
  /**
   * Update the internal code block selection.
   *
   * @param {RTECodeBlockNode} startNode - The internal code block node DTO.
   * @param {number} startOffset - The content offset.
   * @param {boolean} immediatelyRun - Whether to invoke the method immediately.
   */
  enqueueSelectionRangeFutureState(startNode, startOffset, immediatelyRun) {
    this.shouldFocusNode = startNode;
    this.focusNodeOffset = startOffset;
    super.enqueueTheTaskIntoQueue(immediatelyRun);
  }
  /**
   * Check the code block is actually selected or not. Because the Code block is a shadow dom, so can't detect the content selected state.
   * We add two placeholder spans at the begin and end position, we could check the placeholder spans selected state to make sure the code block is selected or not.
   *
   *
   * @example
   * <div>
   * <span></span>
   * <vega-code-block></vega-code-block>
   * <span><span>
   * </div>
   * @param {RTECodeBlock} codeBlock - The code block DTO.
   * @param {Range} range - The range instance.
   * @returns {boolean} - The boolean result.
   */
  isCodeBlockSelected(codeBlock, range) {
    const codeBlockNode = codeBlock.children[0];
    const entityDom = stateEntityRenderingRegistry.getDOMByEntity(codeBlockNode);
    return (codeBlock.isSelected() ||
      (entityDom &&
        range.intersectsNode(entityDom.nextSibling) &&
        range.intersectsNode(entityDom.previousSibling)));
  }
  /**
   * Focus the code block component.
   *
   * @param {RTECodeBlockNode} node - The code block node DTO.
   */
  async focusTheCodeBlock(node) {
    await Promise.resolve();
    const entityDom = stateEntityRenderingRegistry.getDOMByEntity(node);
    if (entityDom) {
      void entityDom.doFocus();
    }
  }
}
