# chuk-motion/tests/test_theme_tools.py
"""
Tests for theme MCP tools.
"""

import json

import pytest

from chuk_motion.tools.theme_tools import register_theme_tools


@pytest.mark.asyncio
class TestThemeTools:
    """Test theme MCP tools."""

    @pytest.fixture
    async def mcp_with_theme_tools(self, mock_mcp_server, project_manager, vfs):
        """Register theme tools and return MCP server."""
        register_theme_tools(mock_mcp_server, project_manager, vfs)
        return mock_mcp_server

    async def test_tools_registered(self, mcp_with_theme_tools):
        """Test that all theme tools are registered."""
        tools = mcp_with_theme_tools.tools

        expected_tools = [
            "remotion_list_themes",
            "remotion_get_theme_info",
            "remotion_search_themes",
            "remotion_compare_themes",
            "remotion_set_current_theme",
            "remotion_get_current_theme",
            "remotion_validate_theme",
            "remotion_create_custom_theme",
            "remotion_export_theme",
            "remotion_import_theme",
            "remotion_get_theme_for_content",
        ]

        for tool in expected_tools:
            assert tool in tools, f"Tool {tool} not registered"

    async def test_list_themes(self, mcp_with_theme_tools):
        """Test remotion_list_themes tool."""
        tool = mcp_with_theme_tools.tools["remotion_list_themes"]
        result = await tool()

        data = json.loads(result)
        assert "themes" in data
        assert len(data["themes"]) > 0

        # Check first theme structure
        first_theme = data["themes"][0]
        assert "key" in first_theme
        assert "name" in first_theme
        assert "description" in first_theme
        assert "primary_color" in first_theme
        assert "use_cases" in first_theme

    async def test_get_theme_info_valid(self, mcp_with_theme_tools):
        """Test getting info for valid theme."""
        tool = mcp_with_theme_tools.tools["remotion_get_theme_info"]
        result = await tool(theme_name="tech")

        data = json.loads(result)
        assert "name" in data
        assert data["name"] == "Tech"
        assert "colors" in data
        assert "typography" in data
        assert "motion" in data

    async def test_get_theme_info_invalid(self, mcp_with_theme_tools):
        """Test getting info for invalid theme."""
        tool = mcp_with_theme_tools.tools["remotion_get_theme_info"]
        result = await tool(theme_name="nonexistent")

        data = json.loads(result)
        assert "error" in data
        assert "available_themes" in data

    async def test_search_themes(self, mcp_with_theme_tools):
        """Test searching themes."""
        tool = mcp_with_theme_tools.tools["remotion_search_themes"]
        result = await tool(query="tech")

        data = json.loads(result)
        assert "query" in data
        assert data["query"] == "tech"
        assert "matches" in data
        assert len(data["matches"]) > 0

    async def test_compare_themes(self, mcp_with_theme_tools):
        """Test comparing two themes."""
        tool = mcp_with_theme_tools.tools["remotion_compare_themes"]
        result = await tool(theme1="tech", theme2="gaming")

        data = json.loads(result)
        assert "themes" in data
        assert data["themes"] == ["tech", "gaming"]
        assert "comparison" in data

        comparison = data["comparison"]
        assert "primary_colors" in comparison
        assert "motion_feel" in comparison

    async def test_set_current_theme_valid(self, mcp_with_theme_tools):
        """Test setting valid current theme."""
        tool = mcp_with_theme_tools.tools["remotion_set_current_theme"]
        result = await tool(theme_name="tech")

        data = json.loads(result)
        assert data["status"] == "success"
        assert data["current_theme"] == "tech"

    async def test_set_current_theme_invalid(self, mcp_with_theme_tools):
        """Test setting invalid current theme."""
        tool = mcp_with_theme_tools.tools["remotion_set_current_theme"]
        result = await tool(theme_name="nonexistent")

        data = json.loads(result)
        assert data["status"] == "error"

    async def test_get_current_theme_none(self, mcp_with_theme_tools):
        """Test getting current theme when none set."""
        tool = mcp_with_theme_tools.tools["remotion_get_current_theme"]
        result = await tool()

        data = json.loads(result)
        assert data["current_theme"] is None

    async def test_get_current_theme_set(self, mcp_with_theme_tools):
        """Test getting current theme after setting."""
        set_tool = mcp_with_theme_tools.tools["remotion_set_current_theme"]
        await set_tool(theme_name="tech")

        get_tool = mcp_with_theme_tools.tools["remotion_get_current_theme"]
        result = await get_tool()

        data = json.loads(result)
        assert data["current_theme"] == "tech"
        assert "info" in data

    async def test_validate_theme_valid(self, mcp_with_theme_tools, sample_theme):
        """Test validating valid theme."""
        tool = mcp_with_theme_tools.tools["remotion_validate_theme"]
        theme_dict = sample_theme.model_dump()
        result = await tool(theme_data=json.dumps(theme_dict))

        data = json.loads(result)
        assert data["valid"] is True
        assert len(data["errors"]) == 0

    async def test_validate_theme_invalid(self, mcp_with_theme_tools):
        """Test validating invalid theme."""
        invalid_data = {"name": "Invalid"}
        tool = mcp_with_theme_tools.tools["remotion_validate_theme"]
        result = await tool(theme_data=json.dumps(invalid_data))

        data = json.loads(result)
        assert data["valid"] is False
        assert len(data["errors"]) > 0

    async def test_validate_theme_bad_json(self, mcp_with_theme_tools):
        """Test validating with invalid JSON."""
        tool = mcp_with_theme_tools.tools["remotion_validate_theme"]
        result = await tool(theme_data="not valid json")

        data = json.loads(result)
        assert data["valid"] is False
        assert "Invalid JSON" in data["errors"][0]

    async def test_create_custom_theme(self, mcp_with_theme_tools):
        """Test creating custom theme."""
        tool = mcp_with_theme_tools.tools["remotion_create_custom_theme"]
        result = await tool(
            name="My Custom",
            description="Custom theme",
            base_theme="tech",
            primary_colors='["#FF0000", "#CC0000", "#990000"]',
        )

        data = json.loads(result)
        assert data["status"] == "success"
        assert "theme_key" in data
        assert "theme" in data

    async def test_create_custom_theme_no_base(self, mcp_with_theme_tools):
        """Test creating custom theme without base (defaults to tech)."""
        tool = mcp_with_theme_tools.tools["remotion_create_custom_theme"]
        result = await tool(
            name="Standalone",
            description="No base theme",
            # Will default to "tech" base theme
        )

        data = json.loads(result)
        # Should succeed with default base
        assert data["status"] == "success"
        assert data["theme_key"] == "standalone"

    async def test_export_theme(self, mcp_with_theme_tools):
        """Test exporting theme."""
        export_path = "exported.json"
        tool = mcp_with_theme_tools.tools["remotion_export_theme"]
        result = await tool(theme_name="tech", file_path=export_path)

        data = json.loads(result)
        assert data["status"] == "success"
        assert "file_path" in data

    async def test_import_theme(self, mcp_with_theme_tools, sample_theme, vfs):
        """Test importing theme."""
        # Create a theme file in vfs - convert Pydantic model to dict first
        theme_dict = sample_theme.model_dump()
        await vfs.write_file("test_theme.json", json.dumps(theme_dict))

        tool = mcp_with_theme_tools.tools["remotion_import_theme"]
        result = await tool(file_path="test_theme.json", theme_key="imported_test")

        data = json.loads(result)
        assert data["status"] == "success"
        assert "Successfully imported" in data["message"]

    async def test_get_theme_for_content(self, mcp_with_theme_tools):
        """Test getting theme recommendations for content type."""
        tool = mcp_with_theme_tools.tools["remotion_get_theme_for_content"]
        result = await tool(content_type="gaming")

        data = json.loads(result)
        assert "content_type" in data
        assert data["content_type"] == "gaming"
        assert "recommendations" in data
        assert len(data["recommendations"]) > 0

    async def test_get_theme_for_unknown_content(self, mcp_with_theme_tools):
        """Test getting theme for unknown content type."""
        tool = mcp_with_theme_tools.tools["remotion_get_theme_for_content"]
        result = await tool(content_type="unknown_xyz")

        data = json.loads(result)
        assert "popular_themes" in data or "recommendations" in data

    async def test_create_custom_theme_invalid_base(self, mcp_with_theme_tools):
        """Test creating custom theme with invalid base theme."""
        tool = mcp_with_theme_tools.tools["remotion_create_custom_theme"]
        result = await tool(
            name="Invalid Base",
            description="Test with invalid base",
            base_theme="nonexistent_theme",
        )

        data = json.loads(result)
        # Should return an error since base theme doesn't exist
        assert "error" in data

    async def test_create_custom_theme_invalid_color_json(self, mcp_with_theme_tools):
        """Test creating custom theme with invalid color JSON."""
        tool = mcp_with_theme_tools.tools["remotion_create_custom_theme"]
        result = await tool(
            name="Bad Colors",
            description="Test with invalid colors",
            base_theme="tech",
            primary_colors="not valid json",
        )

        data = json.loads(result)
        assert "error" in data
        assert "Invalid color JSON" in data["error"]

    async def test_create_custom_theme_with_accent_colors(self, mcp_with_theme_tools):
        """Test creating custom theme with accent colors."""
        tool = mcp_with_theme_tools.tools["remotion_create_custom_theme"]
        result = await tool(
            name="Accented Theme",
            description="Theme with custom accent colors",
            base_theme="tech",
            accent_colors='["#00FF00", "#00CC00"]',
        )

        data = json.loads(result)
        assert data["status"] == "success"
        assert "theme_key" in data

    async def test_export_theme_invalid(self, mcp_with_theme_tools):
        """Test exporting a non-existent theme."""
        tool = mcp_with_theme_tools.tools["remotion_export_theme"]
        result = await tool(theme_name="nonexistent_theme", file_path="test.json")

        data = json.loads(result)
        assert "error" in data

    async def test_import_theme_invalid_file(self, mcp_with_theme_tools):
        """Test importing from non-existent file."""
        tool = mcp_with_theme_tools.tools["remotion_import_theme"]
        result = await tool(file_path="nonexistent_file.json")

        data = json.loads(result)
        assert "error" in data
