#!/usr/bin/env node

/**
 * Test Floating Draggable Menu
 *
 * Tests the new floating, draggable edit menu that shows original content
 * underneath and prevents click propagation issues
 */

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

runner.describe('Floating Draggable Menu Tests', () => {

    runner.it('should create floating menu outside of section element', 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);

            const textMarkdown = '# Test Content\n\nThis is test content.';
            const sections = manager.createSectionsFromMarkdown(textMarkdown);
            const textSection = sections[0];

            const mockElement = document.createElement('div');
            mockElement.setAttribute('data-section-id', textSection.id);
            mockElement.innerHTML = '<h1>Test Content</h1><p>This is test content.</p>';
            renderer.findSectionElement = () => mockElement;

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

            // Verify floating menu exists in document body
            const floatingMenu = document.querySelector('.ui-edit-floating-menu');
            runner.expect(floatingMenu).toBeTruthy();
            runner.expect(floatingMenu.parentElement).toBe(document.body);

            // Verify section ID is stored
            runner.expect(floatingMenu.dataset.sectionId).toBe(textSection.id);

            // Verify original content remains in element
            runner.expect(mockElement.innerHTML).toBe('<h1>Test Content</h1><p>This is test content.</p>');

            // Verify element has highlight styling
            runner.expect(mockElement.style.outline).toBe('2px solid rgb(0, 123, 255)');
            runner.expect(mockElement.style.backgroundColor).toBe('rgba(0, 123, 255, 0.05)');

            // Cleanup
            document.body.removeChild(container);
            if (floatingMenu && floatingMenu.parentElement) {
                floatingMenu.remove();
            }
        }
    });

    runner.it('should create drag handle and make menu draggable', 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);

            const floatingMenu = document.querySelector('.ui-edit-floating-menu');
            const dragHandle = floatingMenu.querySelector('.ui-edit-drag-handle');

            runner.expect(dragHandle).toBeTruthy();
            runner.expect(dragHandle.style.cursor).toBe('move');
            runner.expect(dragHandle.textContent).toContain('Drag to Move');

            // Verify menu has move cursor
            runner.expect(floatingMenu.style.cursor).toBe('move');

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

    runner.it('should have fixed positioning outside document flow', 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);
            Object.defineProperties(mockElement, {
                getBoundingClientRect: {
                    value: () => ({ top: 100, right: 200, bottom: 150, left: 50 })
                }
            });
            renderer.findSectionElement = () => mockElement;

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

            const floatingMenu = document.querySelector('.ui-edit-floating-menu');

            // Verify fixed positioning
            runner.expect(floatingMenu.style.position).toBe('fixed');
            runner.expect(floatingMenu.style.zIndex).toBe('10000');

            // Verify positioned next to element
            runner.expect(parseInt(floatingMenu.style.left)).toBeGreaterThan(200); // Right of element

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

    runner.it('should handle button clicks without propagation', 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;

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

            const floatingMenu = document.querySelector('.ui-edit-floating-menu');
            const cancelBtn = floatingMenu.querySelector('.ui-edit-button-cancel');

            runner.expect(cancelBtn).toBeTruthy();

            // Test getCurrentEditingSectionId works with floating menu
            const sectionId = renderer.getCurrentEditingSectionId(cancelBtn);
            runner.expect(sectionId).toBe(textSection.id);

            // Click cancel button
            cancelBtn.click();

            // Verify menu is removed
            const menuAfterClick = document.querySelector('.ui-edit-floating-menu');
            runner.expect(menuAfterClick).toBeFalsy();

            // Verify element highlighting is removed
            runner.expect(mockElement.style.outline).toBe('');
            runner.expect(mockElement.style.backgroundColor).toBe('');

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

    runner.it('should include makeDraggable method', 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);

            // Verify makeDraggable method exists
            runner.expect(typeof renderer.makeDraggable).toBe('function');

            // Create test elements
            const testElement = document.createElement('div');
            testElement.style.cssText = 'position: fixed; top: 100px; left: 100px; width: 200px; height: 100px;';
            const testHandle = document.createElement('div');
            testHandle.style.cssText = 'width: 100%; height: 20px; cursor: move;';

            testElement.appendChild(testHandle);
            document.body.appendChild(testElement);

            // Apply draggable functionality
            renderer.makeDraggable(testElement, testHandle);

            // Test that event listeners were added (basic check)
            runner.expect(testElement.style.cursor).toBe('move');

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

    runner.it('should create compact button layout in floating menu', 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);

            const floatingMenu = document.querySelector('.ui-edit-floating-menu');
            const controls = floatingMenu.querySelector('.ui-edit-controls');

            // Verify horizontal button layout
            runner.expect(controls.style.display).toBe('flex');
            runner.expect(controls.style.justifyContent).toBe('space-between');

            // Verify all buttons exist
            const acceptBtn = controls.querySelector('.ui-edit-button-accept');
            const cancelBtn = controls.querySelector('.ui-edit-button-cancel');
            const resetBtn = controls.querySelector('.ui-edit-button-reset');

            runner.expect(acceptBtn).toBeTruthy();
            runner.expect(cancelBtn).toBeTruthy();
            runner.expect(resetBtn).toBeTruthy();

            // Verify button styling
            runner.expect(acceptBtn.style.background).toBe('rgb(40, 167, 69)');
            runner.expect(cancelBtn.style.background).toBe('rgb(220, 53, 69)');
            runner.expect(resetBtn.style.background).toBe('rgb(253, 126, 20)');

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

// Run the tests
if (require.main === module) {
    console.log('🎈 Running Floating Draggable Menu 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 - floating menu needs attention`);
        } else {
            console.log('✅ All floating draggable menu tests passed!');
        }
    });
}

module.exports = runner;