import { expect, tap, webhelpers } from '@git.zone/tstest/tapbundle';
import { DeesWysiwygBlock } from '../ts_web/elements/00group-input/dees-input-wysiwyg/dees-wysiwyg-block.js';
import { WysiwygSelection } from '../ts_web/elements/00group-input/dees-input-wysiwyg/wysiwyg.selection.js';

tap.test('Shadow DOM containment should work correctly', async () => {
  console.log('=== Testing Shadow DOM Containment ===');

  // Wait for custom element to be defined
  await customElements.whenDefined('dees-wysiwyg-block');

  // Create a WYSIWYG block component - set properties BEFORE attaching to DOM
  const block = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;

  // Set the block data before attaching to DOM so firstUpdated() sees them
  block.block = {
    id: 'test-1',
    type: 'paragraph',
    content: 'Hello world test content'
  };

  block.handlers = {
    onInput: () => {},
    onKeyDown: () => {},
    onFocus: () => {},
    onBlur: () => {},
    onCompositionStart: () => {},
    onCompositionEnd: () => {}
  };

  // Now attach to DOM and wait for render
  document.body.appendChild(block);
  await block.updateComplete;
  // Wait for firstUpdated to populate the container
  await new Promise(resolve => setTimeout(resolve, 50));
  
  // Get the paragraph element inside Shadow DOM
  const container = block.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLElement;
  const paragraphBlock = container?.querySelector('.block.paragraph') as HTMLElement;
  
  expect(paragraphBlock).toBeTruthy();
  console.log('Found paragraph block:', paragraphBlock);
  console.log('Paragraph text content:', paragraphBlock.textContent);
  
  // Focus the paragraph
  paragraphBlock.focus();
  
  // Manually set cursor position
  const textNode = paragraphBlock.firstChild;
  if (textNode && textNode.nodeType === Node.TEXT_NODE) {
    const range = document.createRange();
    const selection = window.getSelection();
    
    // Set cursor at position 11 (after "Hello world")
    range.setStart(textNode, 11);
    range.setEnd(textNode, 11);
    
    selection?.removeAllRanges();
    selection?.addRange(range);
    
    console.log('Set cursor at position 11');
    
    // Test the containment check
    console.log('\n--- Testing containment ---');
    const currentSelection = window.getSelection();
    if (currentSelection && currentSelection.rangeCount > 0) {
      const selRange = currentSelection.getRangeAt(0);
      console.log('Selection range:', {
        startContainer: selRange.startContainer,
        startOffset: selRange.startOffset,
        containerText: selRange.startContainer.textContent
      });
      
      // Test regular contains (should fail across Shadow DOM)
      const regularContains = paragraphBlock.contains(selRange.startContainer);
      console.log('Regular contains:', regularContains);
      
      // Test Shadow DOM-aware contains
      const shadowDOMContains = WysiwygSelection.containsAcrossShadowDOM(paragraphBlock, selRange.startContainer);
      console.log('Shadow DOM contains:', shadowDOMContains);
      
      // Since we're setting selection within the same shadow DOM, both should be true
      expect(regularContains).toBeTrue();
      expect(shadowDOMContains).toBeTrue();
    }
    
    // Test getSplitContent
    console.log('\n--- Testing getSplitContent ---');
    const splitResult = block.getSplitContent();
    console.log('Split result:', splitResult);
    
    expect(splitResult).toBeTruthy();
    if (splitResult) {
      console.log('Before:', JSON.stringify(splitResult.before));
      console.log('After:', JSON.stringify(splitResult.after));
      
      // Expected split at position 11
      expect(splitResult.before).toEqual('Hello world');
      expect(splitResult.after).toEqual(' test content');
    }
  }

  // Clean up
  document.body.removeChild(block);
});

tap.test('Shadow DOM containment across different shadow roots', async () => {
  console.log('=== Testing Cross Shadow Root Containment ===');
  
  // Create parent component with WYSIWYG editor
  const parentDiv = document.createElement('div');
  parentDiv.innerHTML = `
    <dees-input-wysiwyg>
      <dees-wysiwyg-block></dees-wysiwyg-block>
    </dees-input-wysiwyg>
  `;
  document.body.appendChild(parentDiv);
  
  // Wait for components to be ready
  await new Promise(resolve => setTimeout(resolve, 100));
  
  const wysiwygInput = parentDiv.querySelector('dees-input-wysiwyg') as any;
  const blockElement = wysiwygInput?.shadowRoot?.querySelector('dees-wysiwyg-block') as DeesWysiwygBlock;
  
  if (blockElement) {
    // Set block data
    blockElement.block = {
      id: 'test-2',
      type: 'paragraph',
      content: 'Cross shadow DOM test'
    };
    
    blockElement.handlers = {
      onInput: () => {},
      onKeyDown: () => {},
      onFocus: () => {},
      onBlur: () => {},
      onCompositionStart: () => {},
      onCompositionEnd: () => {}
    };
    
    await blockElement.updateComplete;
    
    // Get the paragraph inside the nested shadow DOM
    const container = blockElement.shadowRoot?.querySelector('.wysiwyg-block-container') as HTMLElement;
    const paragraphBlock = container?.querySelector('.block.paragraph') as HTMLElement;
    
    if (paragraphBlock) {
      console.log('Found nested paragraph block');
      
      // Focus and set selection
      paragraphBlock.focus();
      const textNode = paragraphBlock.firstChild;
      if (textNode && textNode.nodeType === Node.TEXT_NODE) {
        const range = document.createRange();
        range.setStart(textNode, 5);
        range.setEnd(textNode, 5);
        
        const selection = window.getSelection();
        selection?.removeAllRanges();
        selection?.addRange(range);
        
        // Test containment from parent's perspective
        const selRange = selection?.getRangeAt(0);
        if (selRange) {
          // This should fail because it crosses shadow DOM boundary
          const regularContains = wysiwygInput.contains(selRange.startContainer);
          console.log('Parent regular contains:', regularContains);
          expect(regularContains).toBeFalse();
          
          // This should work with our Shadow DOM-aware method
          const shadowDOMContains = WysiwygSelection.containsAcrossShadowDOM(wysiwygInput, selRange.startContainer);
          console.log('Parent shadow DOM contains:', shadowDOMContains);
          expect(shadowDOMContains).toBeTrue();
        }
      }
    }
  }
  
  // Clean up
  document.body.removeChild(parentDiv);
});

export default tap.start();