#!/usr/bin/env node

/**
 * TDD Tests for Enhanced DOM Event System Features
 */

const { TestRunner } = require('./test_runner.js');
const runner = new TestRunner();

// Test enhanced DOM event system advanced features
runner.describe('Enhanced DOM Event System Advanced Features', () => {

    runner.it('should track event statistics and history', async () => {
        // Load editor
        delete require.cache[require.resolve('/home/worsch/markitect_project/markitect/static/editor.js')];
        require('/home/worsch/markitect_project/markitect/static/editor.js');

        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            // Verify event tracking capabilities
            runner.expect(typeof renderer.getEventStats).toBe('function');
            runner.expect(Array.isArray(renderer.eventHistory)).toBeTruthy();
            runner.expect(typeof renderer.eventStats).toBe('object');

            // Initial state should be empty
            const initialStats = renderer.getEventStats();
            runner.expect(initialStats.totalEvents).toBe(0);
            runner.expect(initialStats.recentEvents.length).toBe(0);
        }
    });

    runner.it('should track section-click events with detailed data', async () => {
        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            const sections = manager.createSectionsFromMarkdown('# Test Section\n\nTest content');

            // Simulate click and verify tracking
            const sectionElement = container.querySelector('[data-section-id]');
            if (sectionElement) {
                const clickEvent = new Event('click', { bubbles: true });
                sectionElement.dispatchEvent(clickEvent);

                const stats = renderer.getEventStats();
                runner.expect(stats.stats['section-click']).toBe(1);
                runner.expect(stats.recentEvents.length).toBe(1);
                runner.expect(stats.recentEvents[0].type).toBe('section-click');
                runner.expect(stats.recentEvents[0].data.sectionId).toBeTruthy();
            }
        }
    });

    runner.it('should track hover events separately for enter/leave', async () => {
        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            const sections = manager.createSectionsFromMarkdown('# Test Section\n\nTest content');

            const sectionElement = container.querySelector('[data-section-id]');
            if (sectionElement) {
                // Simulate hover enter and leave
                const mouseEnterEvent = new Event('mouseenter');
                const mouseLeaveEvent = new Event('mouseleave');

                sectionElement.dispatchEvent(mouseEnterEvent);
                sectionElement.dispatchEvent(mouseLeaveEvent);

                const stats = renderer.getEventStats();
                runner.expect(stats.stats['section-hover-enter']).toBe(1);
                runner.expect(stats.stats['section-hover-leave']).toBe(1);
            }
        }
    });

    runner.it('should track keyboard shortcuts with action data', async () => {
        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            const sections = manager.createSectionsFromMarkdown('# Test Section\n\nTest content');
            manager.startEditing(sections[0].id);

            const textarea = container.querySelector('textarea');
            if (textarea) {
                // Simulate Ctrl+Enter
                const keyEvent = new KeyboardEvent('keydown', {
                    key: 'Enter',
                    ctrlKey: true,
                    bubbles: true
                });
                textarea.dispatchEvent(keyEvent);

                const stats = renderer.getEventStats();
                runner.expect(stats.stats['keyboard-shortcut']).toBe(1);

                const shortcutEvent = stats.recentEvents.find(e => e.type === 'keyboard-shortcut');
                if (shortcutEvent) {
                    runner.expect(shortcutEvent.data.shortcut).toBe('ctrl+enter');
                    runner.expect(shortcutEvent.data.action).toBe('accept');
                }
            }
        }
    });

    runner.it('should make sections draggable with proper attributes', async () => {
        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            const sections = manager.createSectionsFromMarkdown('# Test Section\n\nTest content');

            const sectionElements = container.querySelectorAll('[data-section-id]');
            runner.expect(sectionElements.length).toBeGreaterThan(0);

            if (sectionElements.length > 0) {
                const sectionElement = sectionElements[0];

                // Check draggable attribute
                runner.expect(sectionElement.draggable).toBeTruthy();

                // Check accessibility attributes
                runner.expect(sectionElement.tabIndex).toBe(0);
                runner.expect(sectionElement.getAttribute('role')).toBe('article');
                runner.expect(sectionElement.getAttribute('aria-label')).toBeTruthy();

                // Check for drag handle
                const dragHandle = sectionElement.querySelector('.ui-edit-drag-handle');
                runner.expect(dragHandle).toBeTruthy();
            }
        }
    });

    runner.it('should support context menu with proper menu items', async () => {
        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            const sections = manager.createSectionsFromMarkdown('# Test Section\n\nTest content');

            const sectionElement = container.querySelector('[data-section-id]');
            if (sectionElement) {
                // Simulate right-click
                const contextMenuEvent = new Event('contextmenu', { bubbles: true });
                Object.defineProperty(contextMenuEvent, 'clientX', { value: 100 });
                Object.defineProperty(contextMenuEvent, 'clientY', { value: 200 });
                sectionElement.dispatchEvent(contextMenuEvent);

                // Check if context menu was created
                const contextMenu = document.querySelector('.ui-edit-context-menu');
                runner.expect(contextMenu).toBeTruthy();

                if (contextMenu) {
                    // Should have menu items
                    const menuItems = contextMenu.querySelectorAll('div');
                    runner.expect(menuItems.length).toBeGreaterThan(3); // At least 4 items

                    // Clean up
                    contextMenu.remove();
                }

                // Should track the event
                const stats = renderer.getEventStats();
                runner.expect(stats.stats['section-context-menu']).toBe(1);
            }
        }
    });

    runner.it('should support drag and drop event tracking', async () => {
        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            const sections = manager.createSectionsFromMarkdown('# Section 1\n\nContent 1\n\n# Section 2\n\nContent 2');

            const sectionElements = container.querySelectorAll('[data-section-id]');
            if (sectionElements.length >= 2) {
                const source = sectionElements[0];
                const target = sectionElements[1];

                // Simulate drag start
                const dragStartEvent = new Event('dragstart');
                Object.defineProperty(dragStartEvent, 'dataTransfer', {
                    value: {
                        setData: () => {},
                        effectAllowed: null
                    }
                });
                source.dispatchEvent(dragStartEvent);

                // Simulate drag over
                const dragOverEvent = new Event('dragover');
                Object.defineProperty(dragOverEvent, 'dataTransfer', {
                    value: { dropEffect: null }
                });
                Object.defineProperty(dragOverEvent, 'preventDefault', {
                    value: () => {}
                });
                target.dispatchEvent(dragOverEvent);

                const stats = renderer.getEventStats();
                runner.expect(stats.stats['section-drag-start']).toBe(1);
                runner.expect(stats.stats['section-drag-over']).toBe(1);
            }
        }
    });

    runner.it('should handle multiple keyboard shortcuts correctly', async () => {
        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            const sections = manager.createSectionsFromMarkdown('# Test Section\n\nTest content');
            manager.startEditing(sections[0].id);

            const textarea = container.querySelector('textarea');
            if (textarea) {
                // Test different shortcuts
                const shortcuts = [
                    { key: 'Enter', ctrlKey: true, expected: 'ctrl+enter' },
                    { key: 's', ctrlKey: true, expected: 'ctrl+s' },
                    { key: 'Escape', ctrlKey: false, expected: 'escape' }
                ];

                for (const shortcut of shortcuts) {
                    // Need to restart editing for each test
                    if (!sections[0].isEditing()) {
                        manager.startEditing(sections[0].id);
                    }

                    const keyEvent = new KeyboardEvent('keydown', {
                        key: shortcut.key,
                        ctrlKey: shortcut.ctrlKey,
                        bubbles: true
                    });
                    textarea.dispatchEvent(keyEvent);
                }

                const stats = renderer.getEventStats();
                runner.expect(stats.stats['keyboard-shortcut']).toBeGreaterThanOrEqual(3);
            }
        }
    });

    runner.it('should support event history with timestamps', async () => {
        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            const sections = manager.createSectionsFromMarkdown('# Test Section\n\nTest content');

            // Generate multiple events
            const sectionElement = container.querySelector('[data-section-id]');
            if (sectionElement) {
                // Click event
                const clickEvent = new Event('click', { bubbles: true });
                sectionElement.dispatchEvent(clickEvent);

                // Hover events
                const mouseEnterEvent = new Event('mouseenter');
                const mouseLeaveEvent = new Event('mouseleave');
                sectionElement.dispatchEvent(mouseEnterEvent);
                sectionElement.dispatchEvent(mouseLeaveEvent);

                const stats = renderer.getEventStats();
                runner.expect(stats.totalEvents).toBe(3);
                runner.expect(stats.recentEvents.length).toBe(3);

                // Check that events have timestamps
                const hasTimestamps = stats.recentEvents.every(event =>
                    event.timestamp && typeof event.timestamp === 'string'
                );
                runner.expect(hasTimestamps).toBeTruthy();

                // Check that events are properly typed
                const eventTypes = stats.recentEvents.map(e => e.type);
                runner.expect(eventTypes.includes('section-click')).toBeTruthy();
                runner.expect(eventTypes.includes('section-hover-enter')).toBeTruthy();
                runner.expect(eventTypes.includes('section-hover-leave')).toBeTruthy();
            }
        }
    });
});

// Run the tests
if (require.main === module) {
    console.log('⚡ Running Enhanced DOM Event System Advanced Feature Tests');
    runner.run().then(() => {
        console.log('✅ Enhanced DOM event system tests complete!');
    });
}

module.exports = runner;