import { tap, expect, webhelpers } from '@git.zone/tstest/tapbundle';

import * as deesCatalog from '../ts_web/index.js';
import { BlockRegistry } from '../ts_web/elements/00group-input/dees-input-wysiwyg/blocks/block.registry.js';
import { DeesWysiwygBlock } from '../ts_web/elements/00group-input/dees-input-wysiwyg/dees-wysiwyg-block.js';

// Import block registration to ensure handlers are registered
import '../ts_web/elements/00group-input/dees-input-wysiwyg/wysiwyg.blockregistration.js';

tap.test('BlockRegistry should have registered handlers', async () => {
  // Test divider handler
  const dividerHandler = BlockRegistry.getHandler('divider');
  expect(dividerHandler).toBeDefined();
  expect(dividerHandler?.type).toEqual('divider');

  // Test paragraph handler
  const paragraphHandler = BlockRegistry.getHandler('paragraph');
  expect(paragraphHandler).toBeDefined();
  expect(paragraphHandler?.type).toEqual('paragraph');

  // Test heading handlers
  const heading1Handler = BlockRegistry.getHandler('heading-1');
  expect(heading1Handler).toBeDefined();
  expect(heading1Handler?.type).toEqual('heading-1');

  const heading2Handler = BlockRegistry.getHandler('heading-2');
  expect(heading2Handler).toBeDefined();
  expect(heading2Handler?.type).toEqual('heading-2');

  const heading3Handler = BlockRegistry.getHandler('heading-3');
  expect(heading3Handler).toBeDefined();
  expect(heading3Handler?.type).toEqual('heading-3');

  // Test that getAllTypes returns all registered types
  const allTypes = BlockRegistry.getAllTypes();
  expect(allTypes).toContain('divider');
  expect(allTypes).toContain('paragraph');
  expect(allTypes).toContain('heading-1');
  expect(allTypes).toContain('heading-2');
  expect(allTypes).toContain('heading-3');
});

tap.test('should render divider block using handler', async () => {
  // Wait for custom element to be defined
  await customElements.whenDefined('dees-wysiwyg-block');

  // Create element and set properties BEFORE attaching to DOM
  const dividerBlock = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;

  // Set required handlers
  dividerBlock.handlers = {
    onInput: () => {},
    onKeyDown: () => {},
    onFocus: () => {},
    onBlur: () => {},
    onCompositionStart: () => {},
    onCompositionEnd: () => {}
  };

  // Set a divider block
  dividerBlock.block = {
    id: 'test-divider',
    type: 'divider',
    content: ' '
  };

  // Attach to DOM and wait for render
  document.body.appendChild(dividerBlock);
  await dividerBlock.updateComplete;
  // Wait for firstUpdated to populate the container
  await new Promise(resolve => setTimeout(resolve, 50));

  // Check that the divider is rendered
  const dividerElement = dividerBlock.shadowRoot?.querySelector('.block.divider');
  expect(dividerElement).toBeTruthy();
  expect(dividerElement?.getAttribute('tabindex')).toEqual('0');

  // Check for the hr element (divider uses <hr> not .divider-icon)
  const hr = dividerBlock.shadowRoot?.querySelector('hr');
  expect(hr).toBeTruthy();

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

tap.test('should render paragraph block using handler', async () => {
  // Wait for custom element to be defined
  await customElements.whenDefined('dees-wysiwyg-block');

  // Create element and set properties BEFORE attaching to DOM
  const paragraphBlock = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;

  // Set required handlers
  paragraphBlock.handlers = {
    onInput: () => {},
    onKeyDown: () => {},
    onFocus: () => {},
    onBlur: () => {},
    onCompositionStart: () => {},
    onCompositionEnd: () => {},
    onMouseUp: () => {}
  };

  // Set a paragraph block
  paragraphBlock.block = {
    id: 'test-paragraph',
    type: 'paragraph',
    content: 'Test paragraph content'
  };

  // Attach to DOM and wait for render
  document.body.appendChild(paragraphBlock);
  await paragraphBlock.updateComplete;
  // Wait for firstUpdated to populate the container
  await new Promise(resolve => setTimeout(resolve, 50));

  // Check that the paragraph is rendered
  const paragraphElement = paragraphBlock.shadowRoot?.querySelector('.block.paragraph');
  expect(paragraphElement).toBeTruthy();
  expect(paragraphElement?.getAttribute('contenteditable')).toEqual('true');
  expect(paragraphElement?.textContent).toEqual('Test paragraph content');

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

tap.test('should render heading blocks using handler', async () => {
  // Wait for custom element to be defined
  await customElements.whenDefined('dees-wysiwyg-block');

  // Test heading-1 - set properties BEFORE attaching to DOM
  const heading1Block = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;

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

  heading1Block.block = {
    id: 'test-h1',
    type: 'heading-1',
    content: 'Heading 1 Test'
  };

  document.body.appendChild(heading1Block);
  await heading1Block.updateComplete;
  // Wait for firstUpdated to populate the container
  await new Promise(resolve => setTimeout(resolve, 50));

  const h1Element = heading1Block.shadowRoot?.querySelector('.block.heading-1');
  expect(h1Element).toBeTruthy();
  expect(h1Element?.textContent).toEqual('Heading 1 Test');

  // Clean up heading-1
  document.body.removeChild(heading1Block);

  // Test heading-2 - set properties BEFORE attaching to DOM
  const heading2Block = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;

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

  heading2Block.block = {
    id: 'test-h2',
    type: 'heading-2',
    content: 'Heading 2 Test'
  };

  document.body.appendChild(heading2Block);
  await heading2Block.updateComplete;
  // Wait for firstUpdated to populate the container
  await new Promise(resolve => setTimeout(resolve, 50));

  const h2Element = heading2Block.shadowRoot?.querySelector('.block.heading-2');
  expect(h2Element).toBeTruthy();
  expect(h2Element?.textContent).toEqual('Heading 2 Test');

  // Clean up heading-2
  document.body.removeChild(heading2Block);
});

tap.test('paragraph block handler methods should work', async () => {
  // Wait for custom element to be defined
  await customElements.whenDefined('dees-wysiwyg-block');

  // Create element and set properties BEFORE attaching to DOM
  const paragraphBlock = document.createElement('dees-wysiwyg-block') as DeesWysiwygBlock;

  // Set required handlers
  paragraphBlock.handlers = {
    onInput: () => {},
    onKeyDown: () => {},
    onFocus: () => {},
    onBlur: () => {},
    onCompositionStart: () => {},
    onCompositionEnd: () => {},
    onMouseUp: () => {}
  };

  paragraphBlock.block = {
    id: 'test-methods',
    type: 'paragraph',
    content: 'Initial content'
  };

  document.body.appendChild(paragraphBlock);
  await paragraphBlock.updateComplete;
  // Wait for firstUpdated to populate the container
  await new Promise(resolve => setTimeout(resolve, 50));

  // Test getContent
  const content = paragraphBlock.getContent();
  expect(content).toEqual('Initial content');

  // Test setContent
  paragraphBlock.setContent('Updated content');
  await paragraphBlock.updateComplete;
  expect(paragraphBlock.getContent()).toEqual('Updated content');

  // Test that the DOM is updated
  const paragraphElement = paragraphBlock.shadowRoot?.querySelector('.block.paragraph');
  expect(paragraphElement?.textContent).toEqual('Updated content');

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

export default tap.start();