"""
Tests for the Modular Theme System

This module tests the new file-based theme loading system that allows themes
to be defined in separate YAML files for better maintainability.
"""

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

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


class TestModularThemeSystem:
    """Test the modular theme file loading system."""

    def test_theme_loader_imports_successfully(self):
        """Test that the theme loader can be imported."""
        from markitect.themes import get_layered_themes, get_theme, list_themes

        # Should be able to import without errors
        assert callable(get_layered_themes)
        assert callable(get_theme)
        assert callable(list_themes)

    def test_themes_loaded_from_yaml_files(self):
        """Test that themes are loaded from YAML files."""
        from markitect.themes import get_layered_themes

        themes = get_layered_themes()

        # Should have loaded our test themes
        assert 'chatgpt' in themes
        assert 'substack' in themes
        assert 'light' in themes
        assert 'dark' in themes

    def test_theme_structure_validation(self):
        """Test that loaded themes have correct structure."""
        from markitect.themes import get_theme

        chatgpt_theme = get_theme('chatgpt')

        # Should have correct structure
        assert 'scope' in chatgpt_theme
        assert 'properties' in chatgpt_theme
        assert 'metadata' in chatgpt_theme

        # Should have correct values
        assert chatgpt_theme['scope'] == 'document'
        assert 'font_family' in chatgpt_theme['properties']
        assert 'Inter' in chatgpt_theme['properties']['font_family']

    def test_backward_compatibility_with_layered_themes(self):
        """Test that modular themes work with existing LAYERED_THEMES system."""
        from markitect.plugins.builtin.markdown_commands import LAYERED_THEMES

        # Modular themes should be merged into LAYERED_THEMES
        assert 'chatgpt' in LAYERED_THEMES
        assert 'substack' in LAYERED_THEMES

        # Should have expected structure
        chatgpt = LAYERED_THEMES['chatgpt']
        assert chatgpt['scope'] == 'document'
        assert 'Inter' in chatgpt['properties']['font_family']

    def test_theme_scoping_system(self):
        """Test that themes are properly organized by scope."""
        from markitect.themes import theme_registry

        # Load all themes
        all_themes = theme_registry.load_themes()

        # Check scope organization
        document_themes = [name for name, data in all_themes.items()
                         if data.get('scope') == 'document']
        mode_themes = [name for name, data in all_themes.items()
                      if data.get('scope') == 'mode']

        assert 'chatgpt' in document_themes
        assert 'substack' in document_themes
        assert 'light' in mode_themes
        assert 'dark' in mode_themes

    def test_theme_listing_functionality(self):
        """Test theme listing and filtering capabilities."""
        from markitect.themes import list_themes

        # Should list all themes
        all_themes = list_themes()
        assert 'chatgpt' in all_themes
        assert 'substack' in all_themes
        assert 'light' in all_themes

        # Should filter by scope
        document_themes = list_themes(scope='document')
        mode_themes = list_themes(scope='mode')

        assert 'chatgpt' in document_themes
        assert 'substack' in document_themes
        assert 'chatgpt' not in mode_themes
        assert 'light' in mode_themes
        assert 'light' not in document_themes

    def test_theme_metadata_preservation(self):
        """Test that theme metadata is properly preserved."""
        from markitect.themes import get_theme

        chatgpt_theme = get_theme('chatgpt')
        metadata = chatgpt_theme['metadata']

        # Should have metadata
        assert 'name' in metadata
        assert 'description' in metadata
        assert 'author' in metadata
        assert 'version' in metadata
        assert 'file' in metadata

        # Should have correct values
        assert metadata['name'] == 'chatgpt'
        assert 'ChatGPT' in metadata['description']
        assert metadata['author'] == 'Claude Code'
        assert metadata['version'] == '1.0.0'

    def test_cli_integration_with_modular_themes(self):
        """Test CLI integration works with file-based themes."""
        from markitect.cli import cli
        from click.testing import CliRunner

        # Create test content
        test_content = "# Modular Theme Test\n\nTesting file-based theme loading."

        with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
            f.write(test_content)
            input_file = f.name

        try:
            output_file = input_file.replace('.md', '.html')

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

            assert result.exit_code == 0

            # Verify output file exists and contains theme styling
            with open(output_file, 'r') as f:
                html_content = f.read()
                assert 'Inter' in html_content  # ChatGPT font
                assert '#10a37f' in html_content  # ChatGPT accent color

        finally:
            # Clean up
            for file_path in [input_file, output_file]:
                if os.path.exists(file_path):
                    os.unlink(file_path)

    def test_theme_combination_still_works(self):
        """Test that theme combinations work with modular themes."""
        from markitect.plugins.builtin.markdown_commands import parse_theme_string, combine_theme_properties

        # Test combining themes that include file-based ones
        theme_list = parse_theme_string("light,standard,chatgpt")
        combined_styles = combine_theme_properties(theme_list)

        # Should include properties from all themes
        assert 'body_background' in combined_styles  # From light
        assert 'font_family' in combined_styles      # From chatgpt
        assert 'Inter' in combined_styles['font_family']  # ChatGPT font
        assert combined_styles['accent_color'] == '#10a37f'  # ChatGPT green

    def test_fallback_to_inline_themes(self):
        """Test that system falls back gracefully if file loading fails."""
        from markitect.plugins.builtin.markdown_commands import LAYERED_THEMES

        # Even if some themes are in files and some inline, should have both
        # We know 'standard' is still inline, 'chatgpt' is in files
        assert 'standard' in LAYERED_THEMES  # Inline theme
        assert 'chatgpt' in LAYERED_THEMES   # File theme

        # Both should have proper structure
        assert 'scope' in LAYERED_THEMES['standard']
        assert 'scope' in LAYERED_THEMES['chatgpt']

    def test_theme_reload_functionality(self):
        """Test that themes can be reloaded during runtime."""
        from markitect.themes import reload_themes, get_theme

        # Get initial theme
        initial_theme = get_theme('chatgpt')
        assert initial_theme is not None

        # Reload themes
        reload_themes()

        # Should still be able to get theme after reload
        reloaded_theme = get_theme('chatgpt')
        assert reloaded_theme is not None
        assert reloaded_theme['scope'] == 'document'

    def test_yaml_error_handling(self):
        """Test that YAML parsing errors are handled gracefully."""
        from markitect.themes import theme_registry

        # Should not crash even if there are YAML errors
        # (This tests the try/except blocks in the theme loader)
        themes = theme_registry.load_themes()

        # Should still load valid themes even if some have errors
        assert isinstance(themes, dict)
        assert len(themes) > 0