#!/usr/bin/env node

/**
 * Test Click Propagation Fix
 *
 * Tests that button clicks don't propagate through to trigger editing
 * of sections below the overlay
 */

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

runner.describe('Click Propagation Fix Tests', () => {

    runner.it('should prevent cancel button clicks from propagating', 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');
            container.innerHTML = '<div id="markdown-content"></div>';
            document.body.appendChild(container);

            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            // Create multiple sections
            const markdown = '# Section 1\n\nFirst section.\n\n# Section 2\n\nSecond section.';
            const sections = manager.createSectionsFromMarkdown(markdown);
            const section1 = sections[0];
            const section2 = sections[1];

            // Mock elements
            const mockElement1 = document.createElement('div');
            mockElement1.setAttribute('data-section-id', section1.id);
            mockElement1.innerHTML = '<h1>Section 1</h1><p>First section.</p>';

            const mockElement2 = document.createElement('div');
            mockElement2.setAttribute('data-section-id', section2.id);
            mockElement2.innerHTML = '<h1>Section 2</h1><p>Second section.</p>';

            // Track which element is returned for findSectionElement
            let currentEditingSection = null;
            renderer.findSectionElement = (sectionId) => {
                if (sectionId === section1.id) return mockElement1;
                if (sectionId === section2.id) return mockElement2;
                return null;
            };

            // Track showEditor calls to detect unwanted propagation
            let showEditorCalls = [];
            const originalShowEditor = renderer.showEditor;
            renderer.showEditor = function(sectionId, content) {
                showEditorCalls.push(sectionId);
                return originalShowEditor.call(this, sectionId, content);
            };

            // Start editing section 1
            manager.startEditing(section1.id);
            currentEditingSection = section1.id;
            renderer.showEditor(section1.id, section1.currentMarkdown);

            // Clear the tracking array after initial call
            showEditorCalls = [];

            // Get cancel button from section 1 editor
            const cancelBtn = mockElement1.querySelector('.ui-edit-button-cancel');
            runner.expect(cancelBtn).toBeTruthy();

            // Create a mock event with stopPropagation and preventDefault tracking
            let preventDefaultCalled = false;
            let stopPropagationCalled = false;

            const mockEvent = {
                target: cancelBtn,
                preventDefault: () => { preventDefaultCalled = true; },
                stopPropagation: () => { stopPropagationCalled = true; }
            };

            // Simulate cancel button click
            renderer.handleCancel(mockEvent);

            // Verify event prevention methods were called
            runner.expect(preventDefaultCalled).toBeTruthy();
            runner.expect(stopPropagationCalled).toBeTruthy();

            // Verify no additional editor was shown (no propagation to section 2)
            runner.expect(showEditorCalls.length).toBe(0);

            // Cleanup
            document.body.removeChild(container);
        }
    });

    runner.it('should prevent overlay clicks from bubbling through', async () => {
        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            container.innerHTML = '<div id="markdown-content"></div>';
            document.body.appendChild(container);

            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            const textMarkdown = '# Test Section';
            const sections = manager.createSectionsFromMarkdown(textMarkdown);
            const textSection = sections[0];

            const mockElement = document.createElement('div');
            mockElement.setAttribute('data-section-id', textSection.id);
            renderer.findSectionElement = () => mockElement;

            // Show editor
            renderer.showEditor(textSection.id, textSection.currentMarkdown);

            // Get overlay container
            const overlayContainer = mockElement.querySelector('.ui-edit-overlay-container');
            runner.expect(overlayContainer).toBeTruthy();

            // Verify click event listener was added to overlay
            // We can't directly test the event listener, but we can verify the overlay responds to click events
            let clickEventHandled = false;

            // Add a test listener to see if events bubble
            document.addEventListener('click', () => {
                clickEventHandled = true;
            });

            // Create and dispatch a click event on the overlay
            const clickEvent = new Event('click', { bubbles: true });
            let stopPropagationCalled = false;

            const originalStopPropagation = clickEvent.stopPropagation;
            clickEvent.stopPropagation = function() {
                stopPropagationCalled = true;
                originalStopPropagation.call(this);
            };

            overlayContainer.dispatchEvent(clickEvent);

            // Verify stopPropagation was called (meaning our handler is working)
            runner.expect(stopPropagationCalled).toBeTruthy();

            // Cleanup
            document.body.removeChild(container);
        }
    });

    runner.it('should handle all button types with event prevention', async () => {
        if (global.DOMRenderer && global.SectionManager) {
            const container = document.createElement('div');
            container.innerHTML = '<div id="markdown-content"></div>';
            document.body.appendChild(container);

            const manager = new global.SectionManager();
            const renderer = new global.DOMRenderer(manager, container);

            const textMarkdown = '# Test Content';
            const sections = manager.createSectionsFromMarkdown(textMarkdown);
            const textSection = sections[0];

            const mockElement = document.createElement('div');
            mockElement.setAttribute('data-section-id', textSection.id);
            renderer.findSectionElement = () => mockElement;

            renderer.showEditor(textSection.id, textSection.currentMarkdown);

            // Test all three button types
            const buttons = {
                accept: mockElement.querySelector('.ui-edit-button-accept'),
                cancel: mockElement.querySelector('.ui-edit-button-cancel'),
                reset: mockElement.querySelector('.ui-edit-button-reset')
            };

            const handlers = {
                accept: renderer.handleAccept.bind(renderer),
                cancel: renderer.handleCancel.bind(renderer),
                reset: renderer.handleReset.bind(renderer)
            };

            Object.keys(buttons).forEach(buttonType => {
                const button = buttons[buttonType];
                const handler = handlers[buttonType];

                runner.expect(button).toBeTruthy();

                // Create mock event
                let preventDefaultCalled = false;
                let stopPropagationCalled = false;

                const mockEvent = {
                    target: button,
                    preventDefault: () => { preventDefaultCalled = true; },
                    stopPropagation: () => { stopPropagationCalled = true; }
                };

                // Call handler
                handler(mockEvent);

                // Verify event prevention
                runner.expect(preventDefaultCalled).toBeTruthy();
                runner.expect(stopPropagationCalled).toBeTruthy();
            });

            // Cleanup
            document.body.removeChild(container);
        }
    });
});

// Run the tests
if (require.main === module) {
    console.log('🛡️ Running Click Propagation Fix Tests');
    runner.run().then(() => {
        const results = runner.results;
        const failed = results.filter(r => r.status === 'FAIL').length;

        if (failed > 0) {
            console.log(`❌ ${failed} test(s) failed - click propagation issues remain`);
        } else {
            console.log('✅ All click propagation fix tests passed!');
        }
    });
}

module.exports = runner;