"""
Tests for Issue #132: Template System and CSS Injection

This module tests template selection and custom CSS injection functionality
for client-side markdown rendering.
"""

import pytest
import tempfile
import os
from pathlib import Path
from unittest.mock import patch, MagicMock
import json

# 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 TestIssue132TemplateSystem:
    """Test template selection and CSS injection functionality."""

    def setup_method(self):
        """Set up test environment."""
        # Create temporary directory for test outputs
        self.temp_dir = tempfile.mkdtemp()
        self.markdown_content = """# Template Test

This is a test document for template system validation.

## Features
- Multiple templates
- Custom CSS support
- Responsive design
"""

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

    def test_default_template_generates_basic_html(self):
        """Test that default template generates basic HTML structure - Issue #132."""
        input_file = Path(self.temp_dir) / "default.md"
        input_file.write_text(self.markdown_content)

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

        # Template system IS implemented - test actual functionality
        from markitect.cli import cli
        from click.testing import CliRunner

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

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

        html_content = output_file.read_text()

        # Should contain basic HTML5 structure
        assert '<!DOCTYPE html>' in html_content
        assert '<meta charset="utf-8">' in html_content
        assert '<title>' in html_content

    def test_github_template_option(self):
        """Test GitHub-style template selection - Issue #132."""
        input_file = Path(self.temp_dir) / "github.md"
        input_file.write_text(self.markdown_content)

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

        # Template system IS implemented - test GitHub template
        from markitect.cli import cli
        from click.testing import CliRunner

        runner = CliRunner()
        result = 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()
        assert 'border-bottom: 1px solid #d0d7de' in html_content  # GitHub heading style

    def test_template_loading_from_filesystem(self):
        """Test template system uses embedded templates - Issue #132."""
        # Templates are embedded in code, not loaded from filesystem
        # Test that template system provides all expected templates
        from markitect.plugins.builtin.markdown_commands import TEMPLATE_STYLES

        # Should have all expected templates available
        expected_templates = ['basic', 'github', 'academic', 'dark']

        for template_name in expected_templates:
            assert template_name in TEMPLATE_STYLES
            template_config = TEMPLATE_STYLES[template_name]

            # Each template should have required style properties
            assert 'body_color' in template_config
            assert 'font_family' in template_config
            assert 'max_width' in template_config

        # Test that templates are properly formatted with variable placeholders
        from markitect.plugins.builtin.markdown_commands import generate_html_with_embedded_markdown
        test_html = generate_html_with_embedded_markdown("# Test", "Test Title", "basic", "", {})
        # HTML template should be properly formatted
        assert '<!DOCTYPE html>' in test_html
        assert 'Test Title' in test_html
        assert '# Test' in test_html

    def test_template_variable_substitution(self):
        """Test template variable substitution system - Issue #132."""
        input_file = Path(self.temp_dir) / "variables.md"
        input_file.write_text("# Variable Test\n\nTesting substitution.")

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

        # Template engine IS implemented - test actual functionality
        from markitect.cli import cli
        from click.testing import CliRunner

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

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

        html_content = output_file.read_text()

        # Variables should be substituted with actual values
        assert '{{ markdown_json }}' not in html_content  # Should be replaced
        assert '{{ title }}' not in html_content  # Should be replaced
        assert '{{ css_content }}' not in html_content  # Should be replaced

        # Should contain actual markdown content as JSON
        assert '# Variable Test' in html_content

    def test_custom_css_injection(self):
        """Test custom CSS injection into templates - Issue #132."""
        custom_css = """
        body {
            font-family: 'Comic Sans MS', cursive;
            background-color: #f0f0f0;
        }
        .markdown-content {
            max-width: 800px;
            margin: 0 auto;
        }
        """

        # Create CSS file
        css_file = Path(self.temp_dir) / "custom.css"
        css_file.write_text(custom_css)

        input_file = Path(self.temp_dir) / "styled.md"
        input_file.write_text(self.markdown_content)

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

        # CSS injection IS implemented - test actual functionality
        from markitect.cli import cli
        from click.testing import CliRunner

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

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

        html_content = output_file.read_text()
        # Custom CSS should be injected
        assert 'Comic Sans MS' in html_content
        assert 'background-color: #f0f0f0' in html_content

    def test_css_content_embedded_in_html(self):
        """Test that CSS content is properly embedded in HTML - Issue #132."""
        custom_css = "body { color: red; }"
        css_file = Path(self.temp_dir) / "red.css"
        css_file.write_text(custom_css)

        input_file = Path(self.temp_dir) / "red_test.md"
        input_file.write_text("# Red Test\n\nShould be red text.")

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

        # CSS embedding IS implemented - test actual functionality
        from markitect.cli import cli
        from click.testing import CliRunner

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

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

        html_content = output_file.read_text()

        # CSS should be embedded in <style> tags
        assert '<style>' in html_content
        assert 'body { color: red; }' in html_content
        assert '</style>' in html_content

    def test_template_with_markdown_parser_integration(self):
        """Test template integration with JavaScript markdown parser - Issue #132."""
        input_file = Path(self.temp_dir) / "integration.md"
        input_file.write_text("# Integration Test\n\nTesting parser integration.")

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

        # Integration IS implemented - test actual functionality
        from markitect.cli import cli
        from click.testing import CliRunner

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

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

        html_content = output_file.read_text()

        # Should contain markdown parser script
        assert 'marked.min.js' in html_content
        assert 'marked.parse' in html_content
        assert 'Integration Test' in html_content

        # Should contain rendering JavaScript
        assert 'DOMContentLoaded' in html_content
        assert 'getElementById' in html_content
        assert 'innerHTML' in html_content

    def test_multiple_templates_available(self):
        """Test that multiple template options are available - Issue #132."""
        # Test template availability
        template_options = ['basic', 'github', 'academic', 'dark']

        from markitect.plugins.builtin.markdown_commands import md_render_command
        from click.testing import CliRunner

        # Create test markdown file
        input_file = Path(self.temp_dir) / "template_test.md"
        input_file.write_text("# Template Test\n\nTesting multiple templates.")

        runner = CliRunner()

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

            result = runner.invoke(md_render_command, [
                str(input_file),
                '--output', str(output_file),
                '--template', template
            ])

            # Should be able to specify different templates
            assert result.exit_code == 0
            assert output_file.exists()

            # Verify template-specific styling
            html_content = output_file.read_text()
            assert '<title>Template Test</title>' in html_content

    def test_dark_theme_template_specific_styling(self):
        """Test that dark theme has appropriate dark styling - Issue #132."""
        input_file = Path(self.temp_dir) / "dark_test.md"
        input_file.write_text("# Dark Theme Test\n\n> Blockquote test\n\n```code block```")

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

        from markitect.plugins.builtin.markdown_commands import md_render_command
        from click.testing import CliRunner

        runner = CliRunner()
        result = runner.invoke(md_render_command, [
            str(input_file),
            '--output', str(output_file),
            '--template', 'dark'
        ])

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

        html_content = output_file.read_text()

        # Verify dark theme specific colors
        assert 'background-color: #0d1117' in html_content  # Dark background
        assert 'color: #e1e4e8' in html_content  # Light text
        assert 'color: #58a6ff' in html_content  # Blue headings
        assert 'background-color: #161b22' in html_content  # Dark code blocks
        assert 'border-left: 4px solid #58a6ff' in html_content  # Blue blockquote border

    def test_invalid_template_handling(self):
        """Test error handling for invalid template names - Issue #132."""
        input_file = Path(self.temp_dir) / "invalid.md"
        input_file.write_text("# Invalid Template Test")

        # Error handling IS implemented - test invalid template
        from markitect.cli import cli
        from click.testing import CliRunner

        runner = CliRunner()
        result = runner.invoke(cli, [
            'md-render',
            str(input_file),
            '--template', 'nonexistent_template'
        ])

        # Should exit with error code for invalid template choice
        assert result.exit_code != 0
        assert 'invalid choice' in result.output.lower() or 'not one of' in result.output.lower()

    def test_template_title_extraction_from_markdown(self):
        """Test title extraction from markdown for template variables - Issue #132."""
        markdown_with_title = """# Main Title

This document should use "Main Title" as the HTML title.
"""

        input_file = Path(self.temp_dir) / "title_test.md"
        input_file.write_text(markdown_with_title)

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

        # Title extraction IS implemented - test actual functionality
        from markitect.cli import cli
        from click.testing import CliRunner

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

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

        html_content = output_file.read_text()

        # HTML title should be extracted from first heading
        assert '<title>Main Title</title>' in html_content

    def test_responsive_template_css(self):
        """Test that default templates include responsive CSS - Issue #132."""
        input_file = Path(self.temp_dir) / "responsive.md"
        input_file.write_text("# Responsive Test\n\nTesting responsive design.")

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

        # Responsive CSS IS implemented - test actual functionality
        from markitect.cli import cli
        from click.testing import CliRunner

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

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

        html_content = output_file.read_text()

        # Should include viewport meta tag
        assert '<meta name="viewport"' in html_content

        # Should include responsive CSS patterns
        assert 'max-width' in html_content