"""
Theme Tools for Remotion MCP Server

Provides async MCP tools for managing and applying themes to video compositions.
Consolidates all theme-related functionality in one place.
"""

import asyncio
import json
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from chuk_virtual_fs import AsyncVirtualFileSystem

from ..themes.theme_manager import ThemeManager


def register_theme_tools(mcp, project_manager, vfs: "AsyncVirtualFileSystem"):
    """
    Register all theme-related tools with the MCP server.

    Args:
        mcp: ChukMCPServer instance
        project_manager: ProjectManager instance for applying themes
        vfs: Virtual filesystem instance for file operations
    """

    # Create a single theme manager instance with virtual filesystem
    theme_manager = ThemeManager(vfs)

    @mcp.tool
    async def remotion_list_themes() -> str:
        """
        List all available video themes with descriptions.

        Returns a list of built-in YouTube-optimized themes including their
        characteristics, primary colors, and recommended use cases.

        Returns:
            JSON array of themes with metadata

        Example:
            themes = await remotion_list_themes()
            # Returns: tech, finance, education, lifestyle, gaming, minimal, business
        """

        def _list():
            theme_keys = theme_manager.list_themes()
            theme_list = []

            for key in theme_keys:
                theme = theme_manager.get_theme(key)
                if theme:
                    theme_list.append(
                        {
                            "key": key,
                            "name": theme.name,
                            "description": theme.description,
                            "primary_color": theme.colors.primary[0]
                            if theme.colors.primary
                            else "N/A",
                            "accent_color": theme.colors.accent[0]
                            if theme.colors.accent
                            else "N/A",
                            "use_cases": theme.use_cases[:3],  # First 3 use cases
                        }
                    )

            return json.dumps({"themes": theme_list}, indent=2)

        return await asyncio.get_event_loop().run_in_executor(None, _list)

    @mcp.tool
    async def remotion_get_theme_info(theme_name: str) -> str:
        """
        Get detailed information about a specific theme.

        Returns complete theme configuration including colors, typography,
        motion design, and usage recommendations.

        Args:
            theme_name: Theme identifier (e.g., "tech", "finance", "education")

        Returns:
            JSON object with complete theme information

        Example:
            info = await remotion_get_theme_info(theme_name="tech")
            # Returns tech theme with all design tokens
        """

        def _get_info():
            info = theme_manager.get_theme_info(theme_name)

            if not info:
                return json.dumps(
                    {
                        "error": f"Theme '{theme_name}' not found",
                        "available_themes": theme_manager.list_themes(),
                    }
                )

            return json.dumps(info, indent=2)

        return await asyncio.get_event_loop().run_in_executor(None, _get_info)

    @mcp.tool
    async def remotion_search_themes(query: str) -> str:
        """
        Search themes by name, description, or use case.

        Performs a case-insensitive search across theme metadata to help
        find suitable themes for specific content types.

        Args:
            query: Search term (e.g., "gaming", "professional", "education")

        Returns:
            JSON array of matching theme keys

        Example:
            results = await remotion_search_themes(query="professional")
            # Returns: ["business", "minimal", "finance"]
        """

        def _search():
            matches = theme_manager.search_themes(query)
            theme_details = []

            for key in matches:
                theme = theme_manager.get_theme(key)
                if theme:
                    theme_details.append(
                        {
                            "key": key,
                            "name": theme.name,
                            "description": theme.description,
                            "use_cases": theme.use_cases,
                        }
                    )

            return json.dumps({"query": query, "matches": theme_details}, indent=2)

        return await asyncio.get_event_loop().run_in_executor(None, _search)

    @mcp.tool
    async def remotion_compare_themes(theme1: str, theme2: str) -> str:
        """
        Compare two themes side by side.

        Returns a comparison of colors, motion feel, and use cases to help
        choose between themes or understand their differences.

        Args:
            theme1: First theme identifier
            theme2: Second theme identifier

        Returns:
            JSON object with side-by-side comparison

        Example:
            comparison = await remotion_compare_themes(theme1="tech", theme2="gaming")
            # Shows differences in colors, motion, and use cases
        """

        def _compare():
            comparison = theme_manager.compare_themes(theme1, theme2)
            return json.dumps(comparison, indent=2)

        return await asyncio.get_event_loop().run_in_executor(None, _compare)

    @mcp.tool
    async def remotion_set_current_theme(theme_name: str) -> str:
        """
        Set the active theme for the current session.

        Sets the default theme that will be used for new components and
        compositions. This doesn't affect existing compositions.

        Args:
            theme_name: Theme identifier to set as active

        Returns:
            JSON with success status

        Example:
            result = await remotion_set_current_theme(theme_name="gaming")
            # Sets gaming theme as default
        """

        def _set():
            success = theme_manager.set_current_theme(theme_name)

            if success:
                return json.dumps(
                    {
                        "status": "success",
                        "current_theme": theme_name,
                        "message": f"Current theme set to '{theme_name}'",
                    }
                )
            else:
                return json.dumps(
                    {
                        "status": "error",
                        "message": f"Theme '{theme_name}' not found",
                        "available_themes": theme_manager.list_themes(),
                    }
                )

        return await asyncio.get_event_loop().run_in_executor(None, _set)

    @mcp.tool
    async def remotion_get_current_theme() -> str:
        """
        Get the currently active theme.

        Returns the theme key that's currently set as default for new
        compositions and components.

        Returns:
            JSON with current theme information

        Example:
            current = await remotion_get_current_theme()
            # Returns current theme key or null if none set
        """

        def _get():
            current = theme_manager.get_current_theme()

            if current:
                theme_info = theme_manager.get_theme_info(current)
                return json.dumps({"current_theme": current, "info": theme_info}, indent=2)
            else:
                return json.dumps({"current_theme": None, "message": "No theme currently set"})

        return await asyncio.get_event_loop().run_in_executor(None, _get)

    @mcp.tool
    async def remotion_validate_theme(theme_data: str) -> str:
        """
        Validate a theme data structure.

        Checks if a theme JSON has all required fields and proper structure.
        Useful before importing or creating custom themes.

        Args:
            theme_data: JSON string with theme data to validate

        Returns:
            JSON with validation results and any errors

        Example:
            result = await remotion_validate_theme(theme_data='{"name": "Custom", ...}')
            # Returns validation status and error list if invalid
        """

        def _validate():
            try:
                theme_dict = json.loads(theme_data)
                validation = theme_manager.validate_theme(theme_dict)
                return json.dumps(validation, indent=2)
            except json.JSONDecodeError as e:
                return json.dumps({"valid": False, "errors": [f"Invalid JSON: {str(e)}"]})

        return await asyncio.get_event_loop().run_in_executor(None, _validate)

    @mcp.tool
    async def remotion_create_custom_theme(
        name: str,
        description: str,
        base_theme: str | None = None,
        primary_colors: str | None = None,
        accent_colors: str | None = None,
    ) -> str:
        """
        Create a custom theme based on an existing theme.

        Creates a new theme by starting with an existing theme and applying
        custom color overrides. More advanced customization can be done by
        exporting, editing, and importing the theme JSON.

        Args:
            name: Custom theme name
            description: Theme description
            base_theme: Base theme to start from (default: "tech")
            primary_colors: JSON array of primary colors (optional)
            accent_colors: JSON array of accent colors (optional)

        Returns:
            JSON with created theme key and details

        Example:
            theme = await remotion_create_custom_theme(
                name="My Brand",
                description="Custom brand colors",
                base_theme="tech",
                primary_colors='["#FF0000", "#CC0000", "#990000"]',
                accent_colors='["#00FF00", "#00CC00", "#009900"]'
            )
        """

        def _create():
            try:
                # Parse color overrides if provided
                color_overrides = {}
                if primary_colors:
                    color_overrides["primary"] = json.loads(primary_colors)
                if accent_colors:
                    color_overrides["accent"] = json.loads(accent_colors)

                result = theme_manager.create_custom_theme(
                    name=name,
                    description=description,
                    base_theme=base_theme or "tech",
                    color_overrides=color_overrides if color_overrides else None,
                )

                # Check if result is an error message
                if result.startswith("Error"):
                    return json.dumps({"error": result})

                # Success - return theme info
                theme_info = theme_manager.get_theme_info(result)
                return json.dumps(
                    {"status": "success", "theme_key": result, "theme": theme_info}, indent=2
                )

            except json.JSONDecodeError as e:
                return json.dumps({"error": f"Invalid color JSON: {str(e)}"})
            except Exception as e:
                return json.dumps({"error": str(e)})

        return await asyncio.get_event_loop().run_in_executor(None, _create)

    @mcp.tool
    async def remotion_export_theme(theme_name: str, file_path: str | None = None) -> str:
        """
        Export a theme to a JSON file.

        Saves a theme to a JSON file that can be shared, version controlled,
        or edited externally. The file can later be imported.

        Args:
            theme_name: Theme identifier to export
            file_path: Output file path (default: theme_name_theme.json)

        Returns:
            JSON with export status and file path

        Example:
            result = await remotion_export_theme(
                theme_name="tech",
                file_path="my_tech_theme.json"
            )
        """
        result = await theme_manager.export_theme(theme_name, file_path)

        if result.startswith("Error"):
            return json.dumps({"error": result})

        return json.dumps(
            {
                "status": "success",
                "file_path": result,
                "message": f"Theme '{theme_name}' exported successfully",
            },
            indent=2,
        )

    @mcp.tool
    async def remotion_import_theme(file_path: str, theme_key: str | None = None) -> str:
        """
        Import a theme from a JSON file.

        Loads a theme from a JSON file and registers it for use. The theme
        will be available immediately for new compositions.

        Args:
            file_path: Path to theme JSON file
            theme_key: Optional key to register under (default: from file)

        Returns:
            JSON with import status and theme key

        Example:
            result = await remotion_import_theme(
                file_path="custom_theme.json",
                theme_key="my_custom"
            )
        """
        result = await theme_manager.import_theme(file_path, theme_key)

        if result.startswith("Error"):
            return json.dumps({"error": result})

        return json.dumps({"status": "success", "message": result}, indent=2)

    @mcp.tool
    async def remotion_get_theme_for_content(content_type: str) -> str:
        """
        Get recommended themes for a content type.

        Suggests suitable themes based on the type of content you're creating.
        Searches theme use cases and descriptions for matches.

        Args:
            content_type: Type of content (e.g., "tutorial", "vlog", "review")

        Returns:
            JSON with recommended themes

        Example:
            recommendations = await remotion_get_theme_for_content(
                content_type="gaming"
            )
            # Returns gaming theme and possibly tech theme
        """

        def _get():
            matches = theme_manager.search_themes(content_type)

            if not matches:
                # If no direct matches, suggest popular themes
                return json.dumps(
                    {
                        "content_type": content_type,
                        "recommendations": [],
                        "message": "No specific matches found",
                        "popular_themes": ["tech", "minimal", "business"],
                    },
                    indent=2,
                )

            recommendations = []
            for key in matches:
                theme = theme_manager.get_theme(key)
                if theme:
                    recommendations.append(
                        {
                            "key": key,
                            "name": theme.name,
                            "description": theme.description,
                            "use_cases": theme.use_cases,
                        }
                    )

            return json.dumps(
                {"content_type": content_type, "recommendations": recommendations}, indent=2
            )

        return await asyncio.get_event_loop().run_in_executor(None, _get)
