#!/usr/bin/env node

/**
 * TDD Tests for Automatic Section Type Detection
 */

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

// Test automatic section type detection functionality
runner.describe('Automatic Section Type Detection', () => {

    runner.it('should detect heading sections accurately', 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.Section && global.SectionType) {
            const testCases = [
                { markdown: '# Level 1 Heading', expected: 'heading' },
                { markdown: '## Level 2 Heading', expected: 'heading' },
                { markdown: '### Level 3 Heading', expected: 'heading' },
                { markdown: '#### Level 4 Heading', expected: 'heading' },
                { markdown: '##### Level 5 Heading', expected: 'heading' },
                { markdown: '###### Level 6 Heading', expected: 'heading' },
                { markdown: '####### Not a heading (too many #)', expected: 'paragraph' }
            ];

            testCases.forEach(testCase => {
                const detectedType = global.Section.detectType(testCase.markdown);
                runner.expect(detectedType).toBe(testCase.expected);
            });
        }
    });

    runner.it('should detect code block sections accurately', async () => {
        if (global.Section && global.SectionType) {
            const testCases = [
                { markdown: '```javascript\nconsole.log("hello");\n```', expected: 'code' },
                { markdown: '```python\nprint("hello")\n```', expected: 'code' },
                { markdown: '```\nplain code block\n```', expected: 'code' },
                { markdown: '~~~\nalternative code block\n~~~', expected: 'code' },
                { markdown: '    indented code block', expected: 'code' },
                { markdown: '\tindented with tab', expected: 'code' },
                { markdown: '`inline code`', expected: 'paragraph' }
            ];

            testCases.forEach(testCase => {
                const detectedType = global.Section.detectType(testCase.markdown);
                runner.expect(detectedType).toBe(testCase.expected);
            });
        }
    });

    runner.it('should detect list sections accurately', async () => {
        if (global.Section && global.SectionType) {
            const testCases = [
                { markdown: '- Bullet item 1\n- Bullet item 2', expected: 'list' },
                { markdown: '* Bullet item 1\n* Bullet item 2', expected: 'list' },
                { markdown: '+ Bullet item 1\n+ Bullet item 2', expected: 'list' },
                { markdown: '1. Numbered item 1\n2. Numbered item 2', expected: 'list' },
                { markdown: '1) Alternative numbered\n2) Another item', expected: 'list' },
                { markdown: '- [ ] Task item 1\n- [x] Completed task', expected: 'list' },
                { markdown: 'Just some - dashes in text', expected: 'paragraph' }
            ];

            testCases.forEach(testCase => {
                const detectedType = global.Section.detectType(testCase.markdown);
                runner.expect(detectedType).toBe(testCase.expected);
            });
        }
    });

    runner.it('should detect quote/blockquote sections accurately', async () => {
        if (global.Section && global.SectionType) {
            const testCases = [
                { markdown: '> This is a quote', expected: 'quote' },
                { markdown: '> Multi-line quote\n> Second line', expected: 'quote' },
                { markdown: '>> Nested quote', expected: 'quote' },
                { markdown: '> **Bold text in quote**', expected: 'quote' },
                { markdown: 'Not > a quote in middle', expected: 'paragraph' }
            ];

            testCases.forEach(testCase => {
                const detectedType = global.Section.detectType(testCase.markdown);
                runner.expect(detectedType).toBe(testCase.expected);
            });
        }
    });

    runner.it('should detect image sections accurately', async () => {
        if (global.Section && global.SectionType) {
            const testCases = [
                { markdown: '![Alt text](image.jpg)', expected: 'image' },
                { markdown: '![](image.png)', expected: 'image' },
                { markdown: '![Alt text](https://example.com/image.gif)', expected: 'image' },
                { markdown: '![Complex alt text with spaces](./local/image.svg)', expected: 'image' },
                { markdown: '[Not an image](link.html)', expected: 'paragraph' }
            ];

            testCases.forEach(testCase => {
                const detectedType = global.Section.detectType(testCase.markdown);
                runner.expect(detectedType).toBe(testCase.expected);
            });
        }
    });

    runner.it('should detect table sections accurately', async () => {
        if (global.Section && global.SectionType) {
            const testCases = [
                {
                    markdown: '| Header 1 | Header 2 |\n|----------|----------|\n| Cell 1   | Cell 2   |',
                    expected: 'table'
                },
                {
                    markdown: 'Name | Age\n--- | ---\nJohn | 25\nJane | 30',
                    expected: 'table'
                },
                {
                    markdown: '| Simple | Table |\n| --- | --- |',
                    expected: 'table'
                }
            ];

            testCases.forEach(testCase => {
                const detectedType = global.Section.detectType(testCase.markdown);
                runner.expect(detectedType).toBe(testCase.expected);
            });
        }
    });

    runner.it('should detect horizontal rule sections accurately', async () => {
        if (global.Section && global.SectionType) {
            const testCases = [
                { markdown: '---', expected: 'hr' },
                { markdown: '***', expected: 'hr' },
                { markdown: '___', expected: 'hr' },
                { markdown: '----', expected: 'hr' },
                { markdown: '- - -', expected: 'hr' },
                { markdown: '* * *', expected: 'hr' },
                { markdown: '_ _ _', expected: 'hr' },
                { markdown: 'Some text with --- in middle', expected: 'paragraph' }
            ];

            testCases.forEach(testCase => {
                const detectedType = global.Section.detectType(testCase.markdown);
                runner.expect(detectedType).toBe(testCase.expected);
            });
        }
    });

    runner.it('should detect mixed content sections and choose primary type', async () => {
        if (global.Section && global.SectionType) {
            const testCases = [
                {
                    markdown: '# Heading\nWith some paragraph content below',
                    expected: 'heading' // Heading takes precedence
                },
                {
                    markdown: 'Some text\n\n![Image](img.jpg)\n\nMore text',
                    expected: 'image' // Image content detected
                },
                {
                    markdown: 'Introduction\n\n```javascript\ncode();\n```',
                    expected: 'code' // Code block detected
                }
            ];

            testCases.forEach(testCase => {
                const detectedType = global.Section.detectType(testCase.markdown);
                runner.expect(detectedType).toBe(testCase.expected);
            });
        }
    });

    runner.it('should provide confidence scores for type detection', async () => {
        if (global.Section) {
            // Check if advanced detection with confidence is available
            const hasAdvancedDetection = typeof global.Section.detectTypeWithConfidence === 'function';

            if (hasAdvancedDetection) {
                const result = global.Section.detectTypeWithConfidence('# Clear Heading');
                runner.expect(result.type).toBe('heading');
                runner.expect(result.confidence).toBeGreaterThan(0.8);
                runner.expect(Array.isArray(result.alternatives)).toBeTruthy();
            } else {
                // Basic functionality is acceptable
                runner.expect(true).toBeTruthy();
            }
        }
    });

    runner.it('should handle edge cases and malformed markdown', async () => {
        if (global.Section && global.SectionType) {
            const testCases = [
                { markdown: '', expected: 'paragraph' },
                { markdown: '\n\n\n', expected: 'paragraph' },
                { markdown: '   \t   ', expected: 'paragraph' },
                { markdown: '#', expected: 'paragraph' }, // Just a hash
                { markdown: '```', expected: 'paragraph' }, // Incomplete code block
                { markdown: '> ', expected: 'quote' }, // Empty quote
                { markdown: '- ', expected: 'list' }, // Empty list item
            ];

            testCases.forEach(testCase => {
                const detectedType = global.Section.detectType(testCase.markdown);
                runner.expect(['heading', 'code', 'list', 'quote', 'image', 'table', 'hr', 'paragraph'].includes(detectedType)).toBeTruthy();
            });
        }
    });

    runner.it('should support dynamic type redetection when content changes', async () => {
        if (global.Section && global.SectionManager) {
            const manager = new global.SectionManager();
            const sections = manager.createSectionsFromMarkdown('Regular paragraph text');

            const section = sections[0];
            runner.expect(section.type).toBe('paragraph');

            // Start editing and change content to heading
            manager.startEditing(section.id);
            manager.updateContent(section.id, '# Now a heading');

            // Check if type is automatically updated
            const hasAutoRedetection = section.type === 'heading' ||
                                      typeof section.redetectType === 'function';

            if (hasAutoRedetection) {
                runner.expect(section.type).toBe('heading');
            } else {
                // Basic functionality is acceptable
                runner.expect(true).toBeTruthy();
            }
        }
    });
});

// Run the tests
if (require.main === module) {
    console.log('🔍 Running TDD Tests for Automatic Section Type Detection');
    runner.run().then(() => {
        console.log('✅ Section type detection test run complete!');
    });
}

module.exports = runner;