import {
  customElement,
  property,
  static as html,
  DeesElement,
  type TemplateResult,
  cssManager,
  css,
} from '@design.estate/dees-element';

import { type IBlock } from './wysiwyg.types.js';
import { WysiwygBlocks } from './wysiwyg.blocks.js';
import { WysiwygSelection } from './wysiwyg.selection.js';
import { BlockRegistry, type IBlockEventHandlers } from './blocks/index.js';
import './wysiwyg.blockregistration.js';
import { WysiwygShortcuts } from './wysiwyg.shortcuts.js';
import '../../dees-contextmenu/dees-contextmenu.js';
import { themeDefaultStyles } from '../../00theme.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-wysiwyg-block': DeesWysiwygBlock;
  }
}

@customElement('dees-wysiwyg-block')
export class DeesWysiwygBlock extends DeesElement {
  async disconnectedCallback() {
    await super.disconnectedCallback();
    // Clean up selection handler
    if ((this as any)._selectionHandler) {
      document.removeEventListener('selectionchange', (this as any)._selectionHandler);
    }
  }
  @property({ type: Object })
  accessor block: IBlock;

  @property({ type: Boolean })
  accessor isSelected: boolean = false;

  @property({ type: Object })
  accessor handlers: IBlockEventHandlers;

  @property({ type: Object })
  accessor wysiwygComponent: any; // Reference to parent dees-input-wysiwyg

  // Reference to the editable block element
  private blockElement: HTMLDivElement | null = null;
  
  // Track if we've initialized the content
  private contentInitialized: boolean = false;
  
  // Track cursor position
  private lastKnownCursorPosition: number = 0;
  private lastSelectedText: string = '';

  private handlerStylesInjected = false;
  
  // Block types that don't support contenteditable
  private static readonly NON_EDITABLE_TYPES = ['image', 'divider', 'youtube'];
  
  private injectHandlerStyles(): void {
    // Only inject once per instance
    if (this.handlerStylesInjected) return;
    this.handlerStylesInjected = true;
    
    // Get styles from all registered block handlers
    let styles = '';
    const blockTypes = BlockRegistry.getAllTypes();
    for (const type of blockTypes) {
      const handler = BlockRegistry.getHandler(type);
      if (handler) {
        styles += handler.getStyles();
      }
    }
    
    if (styles) {
      // Create and inject style element
      const styleElement = document.createElement('style');
      styleElement.textContent = styles;
      this.shadowRoot?.appendChild(styleElement);
    }
  }

  public static styles = [
    themeDefaultStyles,
    cssManager.defaultStyles,
    css`
      /* TODO: Migrate hardcoded values to --dees-* CSS variables */
      :host {
        display: block;
      }

      .block {
        padding: 4px 0;
        min-height: 1.6em;
        outline: none;
        width: 100%;
        word-wrap: break-word;
        position: relative;
        transition: all 0.15s ease;
        color: ${cssManager.bdTheme('#000000', '#e0e0e0')};
      }

      .block:empty:not(:focus)::before {
        content: attr(data-placeholder);
        color: ${cssManager.bdTheme('#999', '#666')};
        position: absolute;
        pointer-events: none;
      }

      /* Block-specific styles moved to handlers */


      /* Formatting styles */
      .block :is(b, strong) {
        font-weight: 600;
        color: ${cssManager.bdTheme('#000000', '#ffffff')};
      }

      .block :is(i, em) {
        font-style: italic;
      }

      .block u {
        text-decoration: underline;
      }

      .block s {
        text-decoration: line-through;
      }

      .block code {
        font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
        font-size: 0.9em;
        background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.06)', 'rgba(255, 255, 255, 0.1)')};
        padding: 2px 6px;
        border-radius: 3px;
        color: ${cssManager.bdTheme('#d14', '#ff6b6b')};
      }

      .block a {
        color: ${cssManager.bdTheme('#0066cc', '#4d94ff')};
        text-decoration: none;
        border-bottom: 1px solid transparent;
        transition: border-color 0.15s ease;
        cursor: pointer;
      }

      .block a:hover {
        border-bottom-color: ${cssManager.bdTheme('#0066cc', '#4d94ff')};
      }

      /* Code block container and language styles moved to handler */

      /* Selection styles */
      .block ::selection {
        background: ${cssManager.bdTheme('rgba(0, 102, 204, 0.3)', 'rgba(77, 148, 255, 0.3)')};
        color: inherit;
      }


      /* Strike through */
      .block :is(s, strike) {
        text-decoration: line-through;
        opacity: 0.7;
      }


      /* Block margin adjustments based on type */
      :host-context(.block-wrapper:first-child) .block {
        margin-top: 0 !important;
      }

      :host-context(.block-wrapper:last-child) .block {
        margin-bottom: 0;
      }

      /* Selected state */
      .block.selected {
        background: ${cssManager.bdTheme('rgba(0, 102, 204, 0.05)', 'rgba(77, 148, 255, 0.08)')};
        box-shadow: inset 0 0 0 2px ${cssManager.bdTheme('rgba(0, 102, 204, 0.2)', 'rgba(77, 148, 255, 0.2)')};
        border-radius: 4px;
        margin-left: -8px;
        margin-right: -8px;
        padding-left: 8px;
        padding-right: 8px;
      }




    `,
  ];

  protected shouldUpdate(changedProperties: Map<string, any>): boolean {
    // If selection state changed, update the selected class without re-rendering
    if (changedProperties.has('isSelected') && this.block) {
      // Find the block element based on block type
      let element: HTMLElement | null = null;
      
      // Build the specific selector based on block type
      const blockType = this.block.type;
      const selector = `.block.${blockType}`;
      
      element = this.shadowRoot?.querySelector(selector) as HTMLElement;
      
      if (element) {
        if (this.isSelected) {
          element.classList.add('selected');
        } else {
          element.classList.remove('selected');
        }
      }
      return false; // Don't re-render, just update the class
    }
    
    // Never update if only the block content changed
    if (changedProperties.has('block') && this.block) {
      const oldBlock = changedProperties.get('block');
      if (oldBlock && oldBlock.id && oldBlock.type && oldBlock.id === this.block.id && oldBlock.type === this.block.type) {
        // Only content or metadata changed, don't re-render
        return false;
      }
    }
    
    // Only update if the block type or id changes
    return !this.blockElement || this.block?.type !== this.blockElement.dataset.blockType;
  }
  
  public firstUpdated(): void {
    // Mark that content has been initialized
    this.contentInitialized = true;
    
    // Inject handler styles if not already done
    this.injectHandlerStyles();
    
    // First, populate the container with the rendered content
    const container = this.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLDivElement;
    if (container && this.block) {
      container.innerHTML = this.renderBlockContent();
    }
    
    // Check if we have a registered handler for this block type
    if (this.block) {
      const handler = BlockRegistry.getHandler(this.block.type);
      if (handler) {
        const blockElement = this.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLElement;
        if (blockElement) {
          handler.setup(blockElement, this.block, this.handlers);
        }
        return; // Block handler takes care of all setup
      }
    }
    
    // Handle special block types
    
    // Now find the actual editable block element
    const editableBlock = this.shadowRoot?.querySelector('.block') as HTMLDivElement;
    
    // Ensure the block element maintains its content
    if (editableBlock) {
      editableBlock.setAttribute('data-block-id', this.block.id);
      editableBlock.setAttribute('data-block-type', this.block.type);
      
      // Set up all event handlers manually to avoid Lit re-renders
      editableBlock.addEventListener('input', (e) => {
        this.handlers?.onInput?.(e as InputEvent);
        
        // Track cursor position after input
        const pos = this.getCursorPosition(editableBlock);
        if (pos !== null) {
          this.lastKnownCursorPosition = pos;
        }
      });
      
      editableBlock.addEventListener('keydown', (e) => {
        // Track cursor position before keydown
        const pos = this.getCursorPosition(editableBlock);
        if (pos !== null) {
          this.lastKnownCursorPosition = pos;
        }
        
        this.handlers?.onKeyDown?.(e);
      });
      
      
      editableBlock.addEventListener('focus', () => {
        this.handlers?.onFocus?.();
      });
      
      editableBlock.addEventListener('blur', () => {
        this.handlers?.onBlur?.();
      });
      
      editableBlock.addEventListener('compositionstart', () => {
        this.handlers?.onCompositionStart?.();
      });
      
      editableBlock.addEventListener('compositionend', () => {
        this.handlers?.onCompositionEnd?.();
      });
      
      editableBlock.addEventListener('mouseup', (e) => {
        const pos = this.getCursorPosition(editableBlock);
        if (pos !== null) {
          this.lastKnownCursorPosition = pos;
        }
        
        // Selection will be handled by selectionchange event
        this.handlers?.onMouseUp?.(e);
      });
      
      editableBlock.addEventListener('click', () => {
        // Small delay to let browser set cursor position
        setTimeout(() => {
          const pos = this.getCursorPosition(editableBlock);
          if (pos !== null) {
            this.lastKnownCursorPosition = pos;
          }
        }, 0);
      });
      
      // Add selection change handler
      const checkSelection = () => {
        const selection = window.getSelection();
        if (!selection || selection.rangeCount === 0) return;
        
        const selectedText = selection.toString();
        if (selectedText.length === 0) {
          // Clear selection if no text
          if (this.lastSelectedText) {
            this.lastSelectedText = '';
            this.dispatchEvent(new CustomEvent('block-text-selected', {
              detail: {
                text: '',
                blockId: this.block.id,
                hasSelection: false
              },
              bubbles: true,
              composed: true
            }));
          }
          return;
        }
        
        // Get fresh reference to the editable block
        const currentEditableBlock = this.shadowRoot?.querySelector('.block') as HTMLDivElement;
          
        if (!currentEditableBlock) return;
        
        // Get parent wysiwyg component's shadow root
        const parentComponent = this.closest('dees-input-wysiwyg');
        const parentShadowRoot = parentComponent?.shadowRoot;
        
        // Use getComposedRanges with shadow roots as per MDN docs
        const shadowRoots: ShadowRoot[] = [];
        if (parentShadowRoot) shadowRoots.push(parentShadowRoot);
        if (this.shadowRoot) shadowRoots.push(this.shadowRoot);
        
        // Get selection info using our Shadow DOM-aware utility
        const selectionInfo = WysiwygSelection.getSelectionInfo(...shadowRoots);
        if (!selectionInfo) return;
        
        // Check if selection is within this block
        const startInBlock = WysiwygSelection.containsAcrossShadowDOM(currentEditableBlock, selectionInfo.startContainer);
        const endInBlock = WysiwygSelection.containsAcrossShadowDOM(currentEditableBlock, selectionInfo.endContainer);
        
        if (startInBlock || endInBlock) {
          if (selectedText !== this.lastSelectedText) {
            this.lastSelectedText = selectedText;
            
            // Create range and get rect
            const range = WysiwygSelection.createRangeFromInfo(selectionInfo);
            const rect = range.getBoundingClientRect();
            
            // Dispatch event
            this.dispatchEvent(new CustomEvent('block-text-selected', {
              detail: {
                text: selectedText.trim(),
                blockId: this.block.id,
                range: range,
                rect: rect,
                hasSelection: true
              },
              bubbles: true,
              composed: true
            }));
          }
        } else if (this.lastSelectedText) {
          // Clear selection if no longer in this block
          this.lastSelectedText = '';
          this.dispatchEvent(new CustomEvent('block-text-selected', {
            detail: {
              text: '',
              blockId: this.block.id,
              hasSelection: false
            },
            bubbles: true,
            composed: true
          }));
        }
      };
      
      // Listen for selection changes
      document.addEventListener('selectionchange', checkSelection);
      
      // Store the handler for cleanup
      (this as any)._selectionHandler = checkSelection;
      
      // Add keyup handler for cursor position tracking
      editableBlock.addEventListener('keyup', () => {
        // Track cursor position
        const pos = this.getCursorPosition(editableBlock);
        if (pos !== null) {
          this.lastKnownCursorPosition = pos;
        }
      });
      
      // Set initial content if needed
      if (this.block.content) {
        editableBlock.innerHTML = this.block.content;
      }
    }
    
    // Store reference to the block element for quick access
    this.blockElement = editableBlock;
  }

  render(): TemplateResult {
    if (!this.block) return html``;

    // Since we need dynamic content, we'll render an empty container
    // and set the innerHTML in firstUpdated
    return html`<div class="wysiwyg-block-container"></div>`;
  }
  
  private renderBlockContent(): string {
    if (!this.block) return '';

    // Check if we have a registered handler for this block type
    const handler = BlockRegistry.getHandler(this.block.type);
    if (handler) {
      return handler.render(this.block, this.isSelected);
    }

    // Default rendering for blocks without handlers
    const selectedClass = this.isSelected ? ' selected' : '';
    return `
      <div
        class="block ${this.block.type}${selectedClass}"
        contenteditable="true"
      ></div>
    `;
  }



  public focus(): void {
    // Check if we have a registered handler for this block type
    const handler = BlockRegistry.getHandler(this.block.type);
    if (handler && handler.focus) {
      const container = this.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLElement;
      const context = { shadowRoot: this.shadowRoot!, component: this };
      return handler.focus(container, context);
    }
    
    // Handle non-editable blocks
    if (this.block && DeesWysiwygBlock.NON_EDITABLE_TYPES.includes(this.block.type)) {
      const blockElement = this.shadowRoot?.querySelector(`.block.${this.block.type}`) as HTMLDivElement;
      if (blockElement) {
        blockElement.focus();
      }
      return;
    }
    
    // Get the actual editable element
    const editableElement = this.shadowRoot?.querySelector('.block') as HTMLDivElement;
      
    if (!editableElement) return;
    
    // Ensure the element is focusable
    if (!editableElement.hasAttribute('contenteditable')) {
      editableElement.setAttribute('contenteditable', 'true');
    }
    
    editableElement.focus();
    
    // If focus failed, try again after a microtask
    if (document.activeElement !== editableElement && this.shadowRoot?.activeElement !== editableElement) {
      Promise.resolve().then(() => {
        editableElement.focus();
      });
    }
  }
  
  public focusWithCursor(position: 'start' | 'end' | number = 'end'): void {
    // Check if we have a registered handler for this block type
    const handler = BlockRegistry.getHandler(this.block.type);
    if (handler && handler.focusWithCursor) {
      const container = this.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLElement;
      const context = { shadowRoot: this.shadowRoot!, component: this };
      return handler.focusWithCursor(container, position, context);
    }
    
    // Non-editable blocks don't support cursor positioning
    if (this.block && DeesWysiwygBlock.NON_EDITABLE_TYPES.includes(this.block.type)) {
      this.focus();
      return;
    }
    
    // Get the actual editable element
    const editableElement = this.shadowRoot?.querySelector('.block') as HTMLDivElement;
      
    if (!editableElement) return;
    
    // Ensure element is focusable first
    if (!editableElement.hasAttribute('contenteditable')) {
      editableElement.setAttribute('contenteditable', 'true');
    }
    
    // Focus the element
    editableElement.focus();
    
    // Set cursor position after focus is established
    const setCursor = () => {
      if (position === 'start') {
        this.setCursorToStart();
      } else if (position === 'end') {
        this.setCursorToEnd();
      } else if (typeof position === 'number') {
        // Use the new selection utility to set cursor position
        WysiwygSelection.setCursorPosition(editableElement, position);
      }
    };
    
    // Ensure cursor is set after focus
    if (document.activeElement === editableElement || this.shadowRoot?.activeElement === editableElement) {
      setCursor();
    } else {
      // Wait for focus to be established
      Promise.resolve().then(() => {
        if (document.activeElement === editableElement || this.shadowRoot?.activeElement === editableElement) {
          setCursor();
        }
      });
    }
  }
  
  

  /**
   * Get cursor position in the editable element
   */
  public getCursorPosition(element: HTMLElement): number | null {
    // Check if we have a registered handler for this block type
    const handler = BlockRegistry.getHandler(this.block.type);
    if (handler && handler.getCursorPosition) {
      const context = { shadowRoot: this.shadowRoot!, component: this };
      return handler.getCursorPosition(element, context);
    }
    
    // Get parent wysiwyg component's shadow root
    const parentComponent = this.closest('dees-input-wysiwyg');
    const parentShadowRoot = parentComponent?.shadowRoot;
    
    // Get selection info with both shadow roots for proper traversal
    const shadowRoots: ShadowRoot[] = [];
    if (parentShadowRoot) shadowRoots.push(parentShadowRoot);
    if (this.shadowRoot) shadowRoots.push(this.shadowRoot);
    
    const selectionInfo = WysiwygSelection.getSelectionInfo(...shadowRoots);
    console.log('getCursorPosition: Selection info from shadow DOMs:', {
      selectionInfo,
      shadowRootsCount: shadowRoots.length
    });
    
    if (!selectionInfo) {
      console.log('getCursorPosition: No selection found');
      return null;
    }
    
    console.log('getCursorPosition: Range info:', {
      startContainer: selectionInfo.startContainer,
      startOffset: selectionInfo.startOffset,
      collapsed: selectionInfo.collapsed,
      startContainerText: selectionInfo.startContainer.textContent
    });
    
    if (!element.contains(selectionInfo.startContainer)) {
      console.log('getCursorPosition: Range not in element');
      return null;
    }
    
    // Create a range from start of element to cursor position
    const preCaretRange = document.createRange();
    preCaretRange.selectNodeContents(element);
    preCaretRange.setEnd(selectionInfo.startContainer, selectionInfo.startOffset);
    
    // Get the text content length up to cursor
    const position = preCaretRange.toString().length;
    console.log('getCursorPosition: Calculated position:', {
      position,
      preCaretText: preCaretRange.toString(),
      elementText: element.textContent,
      elementTextLength: element.textContent?.length
    });
    
    return position;
  }

  public getContent(): string {
    // Check if we have a registered handler for this block type
    const handler = BlockRegistry.getHandler(this.block.type);
    if (handler && handler.getContent) {
      const container = this.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLElement;
      const context = { shadowRoot: this.shadowRoot!, component: this };
      return handler.getContent(container, context);
    }
    
    
    // Get the actual editable element
    const editableElement = this.shadowRoot?.querySelector('.block') as HTMLDivElement;
      
    if (!editableElement) return '';
    
    // Get the innerHTML which includes formatting tags
    const content = editableElement.innerHTML || '';
    console.log('Getting content from block:', content);
    return content;
  }

  public setContent(content: string): void {
    // Check if we have a registered handler for this block type
    const handler = BlockRegistry.getHandler(this.block.type);
    if (handler && handler.setContent) {
      const container = this.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLElement;
      const context = { shadowRoot: this.shadowRoot!, component: this };
      return handler.setContent(container, content, context);
    }
    
    // Get the actual editable element
    const editableElement = this.shadowRoot?.querySelector('.block') as HTMLDivElement;
      
    if (!editableElement) return;
    
    // Store if we have focus
    const hadFocus = document.activeElement === editableElement || this.shadowRoot?.activeElement === editableElement;
    
    editableElement.innerHTML = content;
    
    // Restore focus if we had it
    if (hadFocus) {
      editableElement.focus();
    }
  }

  public setCursorToStart(): void {
    // Check if we have a registered handler for this block type
    const handler = BlockRegistry.getHandler(this.block.type);
    if (handler && handler.setCursorToStart) {
      const container = this.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLElement;
      const context = { shadowRoot: this.shadowRoot!, component: this };
      return handler.setCursorToStart(container, context);
    }
    
    // Always find the element fresh, don't rely on cached blockElement
    const editableElement = this.shadowRoot?.querySelector('.block') as HTMLDivElement;
    if (editableElement) {
      WysiwygBlocks.setCursorToStart(editableElement);
    }
  }

  public setCursorToEnd(): void {
    // Check if we have a registered handler for this block type
    const handler = BlockRegistry.getHandler(this.block.type);
    if (handler && handler.setCursorToEnd) {
      const container = this.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLElement;
      const context = { shadowRoot: this.shadowRoot!, component: this };
      return handler.setCursorToEnd(container, context);
    }
    
    // Always find the element fresh, don't rely on cached blockElement
    const editableElement = this.shadowRoot?.querySelector('.block') as HTMLDivElement;
    if (editableElement) {
      WysiwygBlocks.setCursorToEnd(editableElement);
    }
  }




  

  
  /**
   * Get context menu items for this block
   */
  public getContextMenuItems(): any[] {
    if (!this.block || this.block.type === 'divider') {
      return [];
    }
    
    const blockTypes = WysiwygShortcuts.getSlashMenuItems();
    const currentType = this.block.type;
    
    // Use the parent reference passed from dees-input-wysiwyg
    const wysiwygComponent = this.wysiwygComponent;
    const blockId = this.block.id;
    
    
    // Create submenu items for block type change
    const blockTypeItems = blockTypes
      .filter(item => item.type !== currentType && item.type !== 'divider')
      .map(item => ({
        name: item.label,
        iconName: item.icon.replace('lucide:', ''),
        action: async () => {
          if (wysiwygComponent && wysiwygComponent.blockOperations) {
            // Transform the block type
            const blockToTransform = wysiwygComponent.blocks.find((b: IBlock) => b.id === blockId);
            if (blockToTransform) {
              blockToTransform.type = item.type;
              blockToTransform.content = blockToTransform.content || '';
              
              // Handle special metadata for different block types
              if (item.type === 'code') {
                blockToTransform.metadata = { language: 'typescript' };
              } else if (item.type === 'list') {
                blockToTransform.metadata = { listType: 'bullet' };
              } else if (item.type === 'image') {
                blockToTransform.content = '';
                blockToTransform.metadata = { url: '', loading: false };
              } else if (item.type === 'youtube') {
                blockToTransform.content = '';
                blockToTransform.metadata = { videoId: '', url: '' };
              } else if (item.type === 'markdown') {
                blockToTransform.metadata = { showPreview: false };
              } else if (item.type === 'html') {
                blockToTransform.metadata = { showPreview: false };
              } else if (item.type === 'attachment') {
                blockToTransform.content = '';
                blockToTransform.metadata = { files: [] };
              }
              
              // Update the block element
              wysiwygComponent.updateBlockElement(blockId);
              wysiwygComponent.updateValue();
              
              // Focus the block after transformation
              requestAnimationFrame(() => {
                wysiwygComponent.blockOperations.focusBlock(blockId);
              });
            }
          }
        }
      }));
    
    const menuItems: any[] = [
      {
        name: 'Change Type',
        iconName: 'type',
        submenu: blockTypeItems
      }
    ];
    
    // Add copy/cut/paste for editable blocks
    if (!['image', 'divider', 'youtube', 'attachment'].includes(this.block.type)) {
      menuItems.push(
        { divider: true },
        {
          name: 'Cut',
          iconName: 'scissors',
          shortcut: 'Cmd+X',
          action: async () => {
            document.execCommand('cut');
          }
        },
        {
          name: 'Copy',
          iconName: 'copy',
          shortcut: 'Cmd+C',
          action: async () => {
            document.execCommand('copy');
          }
        },
        {
          name: 'Paste',
          iconName: 'clipboard',
          shortcut: 'Cmd+V',
          action: async () => {
            document.execCommand('paste');
          }
        }
      );
    }
    
    // Add delete option
    menuItems.push(
      { divider: true },
      {
        name: 'Delete Block',
        iconName: 'trash2',
        action: async () => {
          if (wysiwygComponent && wysiwygComponent.blockOperations) {
            wysiwygComponent.blockOperations.deleteBlock(blockId);
          }
        }
      }
    );
    
    return menuItems;
  }

  /**
   * Gets content split at cursor position
   */
  public getSplitContent(): { before: string; after: string } | null {
    console.log('getSplitContent: Starting...');
    
    // Check if we have a registered handler for this block type
    const handler = BlockRegistry.getHandler(this.block.type);
    console.log('getSplitContent: Checking for handler', { 
      blockType: this.block.type, 
      hasHandler: !!handler,
      hasSplitMethod: !!(handler && handler.getSplitContent)
    });
    
    if (handler && handler.getSplitContent) {
      const container = this.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLElement;
      console.log('getSplitContent: Found container', { 
        container: !!container,
        containerHTML: container?.innerHTML?.substring(0, 100)
      });
      const context = {
        shadowRoot: this.shadowRoot!,
        component: this
      };
      return handler.getSplitContent(container, context);
    }
    
    
    // Get the actual editable element first
    const editableElement = this.shadowRoot?.querySelector('.block') as HTMLDivElement;
      
    if (!editableElement) {
      console.log('getSplitContent: No editable element found');
      return null;
    }
    
    console.log('getSplitContent: Element info:', {
      blockType: this.block.type,
      innerHTML: editableElement.innerHTML,
      textContent: editableElement.textContent,
      textLength: editableElement.textContent?.length
    });
    
    // Get parent wysiwyg component's shadow root
    const parentComponent = this.closest('dees-input-wysiwyg');
    const parentShadowRoot = parentComponent?.shadowRoot;
    
    // Get selection info with both shadow roots for proper traversal
    const shadowRoots: ShadowRoot[] = [];
    if (parentShadowRoot) shadowRoots.push(parentShadowRoot);
    if (this.shadowRoot) shadowRoots.push(this.shadowRoot);
    
    const selectionInfo = WysiwygSelection.getSelectionInfo(...shadowRoots);
    console.log('getSplitContent: Selection info from shadow DOMs:', {
      selectionInfo,
      shadowRootsCount: shadowRoots.length
    });
    
    if (!selectionInfo) {
      console.log('getSplitContent: No selection, using last known position:', this.lastKnownCursorPosition);
      // Try using last known cursor position
      if (this.lastKnownCursorPosition !== null) {
        const fullText = editableElement.textContent || '';
        const pos = Math.min(this.lastKnownCursorPosition, fullText.length);
        console.log('getSplitContent: Splitting with last known position:', {
          pos,
          fullTextLength: fullText.length,
          before: fullText.substring(0, pos),
          after: fullText.substring(pos)
        });
        return {
          before: fullText.substring(0, pos),
          after: fullText.substring(pos)
        };
      }
      return null;
    }
    
    console.log('getSplitContent: Selection range:', {
      startContainer: selectionInfo.startContainer,
      startOffset: selectionInfo.startOffset,
      startContainerInElement: editableElement.contains(selectionInfo.startContainer)
    });
    
    // Make sure the selection is within this block
    if (!WysiwygSelection.containsAcrossShadowDOM(editableElement, selectionInfo.startContainer)) {
      console.log('getSplitContent: Selection not in this block, using last known position:', this.lastKnownCursorPosition);
      // Try using last known cursor position
      if (this.lastKnownCursorPosition !== null) {
        const fullText = editableElement.textContent || '';
        const pos = Math.min(this.lastKnownCursorPosition, fullText.length);
        return {
          before: fullText.substring(0, pos),
          after: fullText.substring(pos)
        };
      }
      return null;
    }
    
    // For HTML content, get cursor position first
    const cursorPos = this.getCursorPosition(editableElement);
    console.log('getSplitContent: Cursor position for HTML split:', cursorPos);
    
    if (cursorPos === null || cursorPos === 0) {
      // If cursor is at start or can't determine position, move all content
      console.log('getSplitContent: Cursor at start or null, moving all content');
      return {
        before: '',
        after: editableElement.innerHTML
      };
    }
    
    // For HTML content, split using ranges to preserve formatting
    const beforeRange = document.createRange();
    const afterRange = document.createRange();
    
    // Before range: from start of element to cursor
    beforeRange.setStart(editableElement, 0);
    beforeRange.setEnd(selectionInfo.startContainer, selectionInfo.startOffset);
    
    // After range: from cursor to end of element
    afterRange.setStart(selectionInfo.startContainer, selectionInfo.startOffset);
    afterRange.setEnd(editableElement, editableElement.childNodes.length);
    
    // Extract HTML content
    const beforeFragment = beforeRange.cloneContents();
    const afterFragment = afterRange.cloneContents();
    
    // Convert to HTML strings
    const tempDiv = document.createElement('div');
    tempDiv.appendChild(beforeFragment);
    const beforeHtml = tempDiv.innerHTML;
    
    tempDiv.innerHTML = '';
    tempDiv.appendChild(afterFragment);
    const afterHtml = tempDiv.innerHTML;
    
    console.log('getSplitContent: Final split result:', {
      cursorPos,
      beforeHtml,
      beforeLength: beforeHtml.length,
      beforeHtmlPreview: beforeHtml.substring(0, 100) + (beforeHtml.length > 100 ? '...' : ''),
      afterHtml,
      afterLength: afterHtml.length,
      afterHtmlPreview: afterHtml.substring(0, 100) + (afterHtml.length > 100 ? '...' : '')
    });
    
    return { 
      before: beforeHtml, 
      after: afterHtml 
    };
  }
  
}
