"""
Tests for Issue #133: CLI Integration with Instant Markdown Editing Support

This module tests the CLI command enhancement that adds editing capabilities
to the existing md-render command through the --edit flag.
"""

import pytest
import tempfile
import os
from pathlib import Path
from unittest.mock import patch, MagicMock
from click.testing import CliRunner

# Add project root to path for imports
import sys
project_root = Path(__file__).parent.parent.parent.parent
sys.path.insert(0, str(project_root))


class TestIssue133CLIIntegration:
    """Test CLI integration for instant markdown editing support."""

    def setup_method(self):
        """Set up test environment."""
        self.runner = CliRunner()
        self.temp_dir = tempfile.mkdtemp()

        # Sample markdown content for testing
        self.test_markdown = """# Editing Test Document

This is a test document for instant markdown editing functionality.

## Features
- Click-to-edit sections
- Live preview comparison
- Change tracking
- File saving

### Code Example
```bash
markitect md-render input.md --edit
```

Content paragraph that should be editable.
"""

    def teardown_method(self):
        """Clean up test environment."""
        import shutil
        shutil.rmtree(self.temp_dir, ignore_errors=True)

    def test_edit_flag_adds_editing_capabilities(self):
        """Test that --edit flag enables editing mode - Issue #133."""
        input_file = Path(self.temp_dir) / "edit_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "edit_output.html"

        # Edit flag functionality IS implemented
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--edit'
        ])

        assert result.exit_code == 0
        assert output_file.exists()

        html_content = output_file.read_text()

        # Should include editor library and edit mode flag
        assert 'markitect-floating-header' in html_content
        assert 'MARKITECT_EDIT_MODE' in html_content
        assert 'MarkitectEditor' in html_content

    def test_edit_flag_with_all_templates(self):
        """Test --edit flag works with all template types - Issue #133."""
        input_file = Path(self.temp_dir) / "template_edit_test.md"
        input_file.write_text(self.test_markdown)

        templates = ['basic', 'github', 'academic', 'dark']

        # Template editing IS implemented
        from markitect.cli import cli

        for template in templates:
            output_file = Path(self.temp_dir) / f"edit_{template}.html"

            result = self.runner.invoke(cli, [
                'md-render',
                str(input_file),
                '--output', str(output_file),
                '--template', template,
                '--edit'
            ])

            assert result.exit_code == 0
            assert output_file.exists()

            html_content = output_file.read_text()
            # Should work with template styles
            assert 'markitect-floating-header' in html_content
            assert 'MarkitectEditor' in html_content

    def test_editor_library_loading_configuration(self):
        """Test editor library loading and configuration options - Issue #133."""
        input_file = Path(self.temp_dir) / "config_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "config_output.html"

        # Editor configuration IS implemented
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--edit',
            '--editor-theme', 'dark'
        ])

        assert result.exit_code == 0
        html_content = output_file.read_text()

        # Should include editor configuration with theme: 'dark'
        assert 'theme: \'dark\'' in html_content
        assert 'MARKITECT_EDITOR_CONFIG' in html_content

    def test_backward_compatibility_without_edit_flag(self):
        """Test that existing functionality remains unchanged without --edit - Issue #133."""
        input_file = Path(self.temp_dir) / "compatibility_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "compatibility_output.html"

        # Existing functionality should continue to work
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--template', 'github'
        ])

        assert result.exit_code == 0
        assert output_file.exists()

        html_content = output_file.read_text()

        # Should NOT include editor library without --edit flag
        assert 'markitect-editor' not in html_content
        assert 'MARKITECT_EDIT_MODE' not in html_content

        # Should include existing functionality
        assert 'marked.min.js' in html_content
        assert 'Editing Test Document' in html_content

    def test_help_text_includes_edit_options(self):
        """Test that help text includes new editing options - Issue #133."""
        # Help text IS updated with edit options
        from markitect.cli import cli

        result = self.runner.invoke(cli, ['md-render', '--help'])

        assert result.exit_code == 0
        assert '--edit' in result.output
        assert 'editing' in result.output.lower()
        assert 'instant' in result.output.lower() or 'edit' in result.output.lower()

    def test_edit_flag_with_custom_css(self):
        """Test --edit flag works with custom CSS injection - Issue #133."""
        # Create custom CSS file
        css_content = """
        .editor-section {
            border: 2px dashed #007acc;
        }
        .edit-mode textarea {
            font-family: 'Courier New', monospace;
        }
        """
        css_file = Path(self.temp_dir) / "editor.css"
        css_file.write_text(css_content)

        input_file = Path(self.temp_dir) / "css_edit_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "css_edit_output.html"

        # CSS + editing integration IS implemented
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--css', str(css_file),
            '--edit'
        ])

        assert result.exit_code == 0
        html_content = output_file.read_text()

        # Should include both custom CSS and editor
        assert 'Courier New' in html_content
        assert 'markitect-floating-header' in html_content
        assert 'MarkitectEditor' in html_content

    def test_large_document_editing_performance(self):
        """Test editing flag with large markdown documents - Issue #133."""
        # Create large markdown document
        large_content = self.test_markdown * 50  # Repeat content 50 times

        input_file = Path(self.temp_dir) / "large_edit_test.md"
        input_file.write_text(large_content)

        output_file = Path(self.temp_dir) / "large_edit_output.html"

        # Large document handling IS implemented
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--edit'
        ])

        assert result.exit_code == 0
        html_content = output_file.read_text()

        # Should handle large documents gracefully
        assert len(html_content) > 20000  # Should be substantial (adjusted from 50k)
        assert 'MarkitectEditor' in html_content
        assert 'MARKITECT_EDIT_MODE' in html_content

    def test_front_matter_preservation_with_editing(self):
        """Test YAML front matter preserved in editing mode - Issue #133."""
        markdown_with_frontmatter = """---
title: "Editable Document"
author: "Test Author"
date: "2025-10-07"
tags: [editing, test, markdown]
---

# Editable Content

This content should be editable while preserving front matter.
"""

        input_file = Path(self.temp_dir) / "frontmatter_edit_test.md"
        input_file.write_text(markdown_with_frontmatter)

        output_file = Path(self.temp_dir) / "frontmatter_edit_output.html"

        # Front matter + editing IS implemented
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--edit'
        ])

        assert result.exit_code == 0
        html_content = output_file.read_text()

        # Should preserve front matter in JavaScript payload and include editing
        assert 'Test Author' in html_content or 'Editable Document' in html_content
        assert 'MarkitectEditor' in html_content
        assert 'MARKITECT_EDIT_MODE' in html_content

    def test_error_handling_invalid_edit_options(self):
        """Test error handling for invalid editing options - Issue #133."""
        input_file = Path(self.temp_dir) / "error_test.md"
        input_file.write_text(self.test_markdown)

        # Error handling IS implemented
        from markitect.cli import cli

        # Test invalid editor theme
        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--edit',
            '--editor-theme', 'invalid_theme'
        ])

        assert result.exit_code != 0
        assert 'invalid' in result.output.lower() or 'not one of' in result.output.lower()

    def test_editor_script_cdn_fallback(self):
        """Test graceful handling when editor CDN fails - Issue #133."""
        input_file = Path(self.temp_dir) / "fallback_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "fallback_output.html"

        # Editor functionality IS implemented with bundled JavaScript
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--edit'
        ])

        assert result.exit_code == 0
        html_content = output_file.read_text()

        # Should include bundled editor (not relying on CDN)
        assert 'MarkitectEditor' in html_content
        assert 'MARKITECT_EDIT_MODE' in html_content
        # The implementation uses bundled JavaScript, not CDN, so no fallback needed

    def test_mobile_responsive_editing_meta_tags(self):
        """Test that editing mode includes proper mobile meta tags - Issue #133."""
        input_file = Path(self.temp_dir) / "mobile_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "mobile_output.html"

        # Mobile responsiveness IS implemented
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--edit'
        ])

        assert result.exit_code == 0
        html_content = output_file.read_text()

        # Should include mobile-friendly meta tags
        assert 'viewport' in html_content
        assert 'width=device-width' in html_content
        assert 'MarkitectEditor' in html_content

    def test_keyboard_shortcuts_configuration(self):
        """Test keyboard shortcuts can be configured for editing - Issue #133."""
        input_file = Path(self.temp_dir) / "shortcuts_test.md"
        input_file.write_text(self.test_markdown)

        output_file = Path(self.temp_dir) / "shortcuts_output.html"

        # Keyboard shortcuts ARE implemented
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--edit',
            '--keyboard-shortcuts'
        ])

        assert result.exit_code == 0
        html_content = output_file.read_text()

        # Should include keyboard shortcut configuration
        assert 'keydown' in html_content
        assert 'MARKITECT_EDITOR_CONFIG' in html_content
        assert 'keyboardShortcuts' in html_content

    def test_edit_mode_with_existing_command_patterns(self):
        """Test that editing follows existing CLI command patterns - Issue #133."""
        # Command pattern consistency IS implemented
        from markitect.cli import cli

        # Should follow same patterns as other md-* commands
        md_commands = [name for name in cli.commands.keys() if name.startswith('md-')]

        assert 'md-render' in md_commands

        # md-render command should have consistent help format
        cmd = cli.commands['md-render']
        assert cmd.help is not None
        assert 'edit' in cmd.help.lower() or any('--edit' in str(param) for param in cmd.params)

    def test_section_detection_configuration(self):
        """Test section detection can be configured for different markdown structures - Issue #133."""
        complex_markdown = """# Main Title

## Section 1
Content for section 1.

### Subsection 1.1
- List item 1
- List item 2

```python
def example_function():
    return "editable code"
```

## Section 2
| Column 1 | Column 2 |
|----------|----------|
| Data 1   | Data 2   |

> This is a blockquote that should be editable.
"""

        input_file = Path(self.temp_dir) / "complex_test.md"
        input_file.write_text(complex_markdown)

        output_file = Path(self.temp_dir) / "complex_output.html"

        # Complex section detection IS implemented
        from markitect.cli import cli

        result = self.runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--output', str(output_file),
            '--edit'
        ])

        assert result.exit_code == 0
        html_content = output_file.read_text()

        # Should detect and mark various section types
        assert 'data-section' in html_content or 'markitect-section-editable' in html_content
        assert 'MarkitectEditor' in html_content