"""
Translation Dictionary Integration for MCP

Provides tools for managing translation dictionaries, theme configuration,
and code generation for design system tokens.

This module wraps the dss.translations Python core to expose these
capabilities through MCP tools.
"""

import asyncio
import json
from typing import Dict, Any, Optional, List
from pathlib import Path
from datetime import datetime
from mcp import types

from .base import BaseIntegration
from ..context.project_context import get_context_manager


# =============================================================================
# MCP Tool Definitions
# =============================================================================

TRANSLATION_TOOLS = [
    # Category 1: Dictionary Management (5 tools)
    types.Tool(
        name="translation_list_dictionaries",
        description="List all available translation dictionaries for a project. Returns dictionary types (figma, css, heroui, custom, etc.), mapping counts, and validation status.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "include_stats": {
                    "type": "boolean",
                    "description": "Include mapping statistics (default: true)",
                    "default": True
                }
            },
            "required": ["project_id"]
        }
    ),
    types.Tool(
        name="translation_get_dictionary",
        description="Get detailed information about a specific translation dictionary including all token mappings, component mappings, and custom props.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "source": {
                    "type": "string",
                    "description": "Dictionary source type",
                    "enum": ["figma", "css", "scss", "heroui", "shadcn", "tailwind", "json", "custom"]
                },
                "include_unmapped": {
                    "type": "boolean",
                    "description": "Include list of unmapped source tokens (default: true)",
                    "default": True
                }
            },
            "required": ["project_id", "source"]
        }
    ),
    types.Tool(
        name="translation_create_dictionary",
        description="Create a new translation dictionary for a project. Maps external tokens (Figma, CSS, etc.) to DSS canonical tokens.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "source": {
                    "type": "string",
                    "description": "Source type for the dictionary",
                    "enum": ["figma", "css", "scss", "heroui", "shadcn", "tailwind", "json", "custom"]
                },
                "token_mappings": {
                    "type": "object",
                    "description": "Token mappings: source_token -> DSS canonical path",
                    "additionalProperties": {
                        "type": "string"
                    }
                },
                "component_mappings": {
                    "type": "object",
                    "description": "Component mappings: source_component -> DSS component",
                    "additionalProperties": {
                        "type": "string"
                    }
                },
                "custom_props": {
                    "type": "object",
                    "description": "Custom properties (must use DSS namespace like 'color.brand.myproject.primary')",
                    "additionalProperties": {}
                },
                "notes": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Human-readable notes"
                }
            },
            "required": ["project_id", "source"]
        }
    ),
    types.Tool(
        name="translation_update_dictionary",
        description="Update an existing translation dictionary. Add or modify token mappings, component mappings, or custom props.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "source": {
                    "type": "string",
                    "description": "Dictionary source type to update",
                    "enum": ["figma", "css", "scss", "heroui", "shadcn", "tailwind", "json", "custom"]
                },
                "token_mappings": {
                    "type": "object",
                    "description": "Token mappings to add/update",
                    "additionalProperties": {"type": "string"}
                },
                "component_mappings": {
                    "type": "object",
                    "description": "Component mappings to add/update",
                    "additionalProperties": {"type": "string"}
                },
                "custom_props": {
                    "type": "object",
                    "description": "Custom props to add/update",
                    "additionalProperties": {}
                },
                "remove_tokens": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Source tokens to remove from mappings"
                },
                "notes": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Notes to append"
                }
            },
            "required": ["project_id", "source"]
        }
    ),
    types.Tool(
        name="translation_validate_dictionary",
        description="Validate a translation dictionary. Checks schema compliance, DSS token path validity, and detects conflicts.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "source": {
                    "type": "string",
                    "description": "Dictionary source type to validate",
                    "enum": ["figma", "css", "scss", "heroui", "shadcn", "tailwind", "json", "custom"]
                },
                "strict": {
                    "type": "boolean",
                    "description": "Strict mode - unknown tokens are errors (default: false)",
                    "default": False
                }
            },
            "required": ["project_id", "source"]
        }
    ),

    # Category 2: Theme Configuration (4 tools)
    types.Tool(
        name="theme_get_config",
        description="Get project theme configuration including base theme, loaded dictionaries, and custom props summary.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                }
            },
            "required": ["project_id"]
        }
    ),
    types.Tool(
        name="theme_resolve",
        description="Resolve complete project theme by merging base theme with translation dictionaries and custom props. Returns fully resolved tokens with provenance.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "base_theme": {
                    "type": "string",
                    "description": "Base theme to use",
                    "enum": ["light", "dark"],
                    "default": "light"
                },
                "include_provenance": {
                    "type": "boolean",
                    "description": "Include token resolution provenance chain (default: false)",
                    "default": False
                }
            },
            "required": ["project_id"]
        }
    ),
    types.Tool(
        name="theme_add_custom_prop",
        description="Add a custom property to the project's custom.json translation dictionary. Custom props extend DSS with project-specific tokens.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "prop_name": {
                    "type": "string",
                    "description": "Property name using DSS namespace (e.g., 'color.brand.acme.primary')"
                },
                "prop_value": {
                    "description": "Property value (string, number, or object)"
                },
                "description": {
                    "type": "string",
                    "description": "Optional description of the custom prop"
                }
            },
            "required": ["project_id", "prop_name", "prop_value"]
        }
    ),
    types.Tool(
        name="theme_get_canonical_tokens",
        description="Get the DSS canonical token structure. Useful for understanding available tokens and valid mapping targets.",
        inputSchema={
            "type": "object",
            "properties": {
                "category": {
                    "type": "string",
                    "description": "Filter by category (optional)",
                    "enum": ["color", "spacing", "typography", "border", "shadow", "motion", "zIndex", "opacity", "breakpoint"]
                },
                "include_aliases": {
                    "type": "boolean",
                    "description": "Include token aliases (default: true)",
                    "default": True
                },
                "include_components": {
                    "type": "boolean",
                    "description": "Include canonical components (default: false)",
                    "default": False
                }
            },
            "required": []
        }
    ),

    # Category 3: Code Generation (3 tools)
    types.Tool(
        name="codegen_export_css",
        description="Generate CSS custom properties from resolved project theme. Outputs :root variables and optional utility classes.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "base_theme": {
                    "type": "string",
                    "description": "Base theme to use",
                    "enum": ["light", "dark"],
                    "default": "light"
                },
                "selector": {
                    "type": "string",
                    "description": "CSS selector for variables (default: ':root')",
                    "default": ":root"
                },
                "prefix": {
                    "type": "string",
                    "description": "CSS variable prefix (default: 'dss')",
                    "default": "dss"
                },
                "include_comments": {
                    "type": "boolean",
                    "description": "Include provenance comments (default: true)",
                    "default": True
                },
                "output_path": {
                    "type": "string",
                    "description": "Optional: Write to file instead of returning content"
                }
            },
            "required": ["project_id"]
        }
    ),
    types.Tool(
        name="codegen_export_scss",
        description="Generate SCSS variables from resolved project theme. Outputs $variables and optional mixins.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "base_theme": {
                    "type": "string",
                    "description": "Base theme to use",
                    "enum": ["light", "dark"],
                    "default": "light"
                },
                "prefix": {
                    "type": "string",
                    "description": "SCSS variable prefix (default: 'dss')",
                    "default": "dss"
                },
                "generate_map": {
                    "type": "boolean",
                    "description": "Generate SCSS map in addition to variables (default: true)",
                    "default": True
                },
                "output_path": {
                    "type": "string",
                    "description": "Optional: Write to file instead of returning content"
                }
            },
            "required": ["project_id"]
        }
    ),
    types.Tool(
        name="codegen_export_json",
        description="Export resolved theme as JSON. Useful for design tool integrations and token documentation.",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "base_theme": {
                    "type": "string",
                    "description": "Base theme to use",
                    "enum": ["light", "dark"],
                    "default": "light"
                },
                "format": {
                    "type": "string",
                    "description": "JSON structure format",
                    "enum": ["flat", "nested", "style-dictionary"],
                    "default": "flat"
                },
                "include_metadata": {
                    "type": "boolean",
                    "description": "Include resolution metadata (default: true)",
                    "default": True
                },
                "output_path": {
                    "type": "string",
                    "description": "Optional: Write to file instead of returning content"
                }
            },
            "required": ["project_id"]
        }
    ),
]


# =============================================================================
# Integration Class
# =============================================================================

class TranslationIntegration(BaseIntegration):
    """Translation dictionary integration wrapper for DSS tools"""

    def __init__(self, config: Optional[Dict[str, Any]] = None):
        """
        Initialize Translation integration.

        Args:
            config: Optional configuration
        """
        super().__init__("translations", config or {})
        self.context_manager = get_context_manager()

    async def _get_project_path(self, project_id: str) -> Path:
        """
        Get project path from context manager.

        Args:
            project_id: Project ID

        Returns:
            Project path as Path object
        """
        context = await self.context_manager.get_context(project_id)
        if not context or not context.path:
            raise ValueError(f"Project not found: {project_id}")
        return Path(context.path)

    # =========================================================================
    # Category 1: Dictionary Management
    # =========================================================================

    async def list_dictionaries(
        self,
        project_id: str,
        include_stats: bool = True
    ) -> Dict[str, Any]:
        """
        List all translation dictionaries for project.

        Args:
            project_id: Project ID
            include_stats: Include statistics

        Returns:
            Dictionary list with metadata
        """
        try:
            from dss.translations.loader import TranslationDictionaryLoader

            project_path = await self._get_project_path(project_id)
            loader = TranslationDictionaryLoader(str(project_path))

            # Get available dictionaries
            available_files = []
            if loader.translations_dir.exists():
                available_files = [f.stem for f in loader.translations_dir.glob("*.json")]

            result = {
                "project_id": project_id,
                "dictionaries": [],
                "has_translations": bool(available_files),
                "translations_dir": str(loader.get_translations_dir())
            }

            if include_stats and available_files:
                # Load registry to get statistics
                registry = await loader.load_all()
                for source in available_files:
                    dict_info = {
                        "source": source,
                        "file": f"{source}.json"
                    }
                    if source in registry.dictionaries:
                        d = registry.dictionaries[source]
                        dict_info["token_count"] = len(d.mappings.tokens)
                        dict_info["component_count"] = len(d.mappings.components)
                        dict_info["custom_prop_count"] = len(d.custom_props)
                        dict_info["unmapped_count"] = len(d.unmapped)
                    result["dictionaries"].append(dict_info)

                result["conflicts"] = registry.conflicts
            else:
                result["dictionaries"] = [{"source": s} for s in available_files]

            return result

        except Exception as e:
            return {
                "error": f"Failed to list dictionaries: {str(e)}",
                "project_id": project_id
            }

    async def get_dictionary(
        self,
        project_id: str,
        source: str,
        include_unmapped: bool = True
    ) -> Dict[str, Any]:
        """
        Get translation dictionary details.

        Args:
            project_id: Project ID
            source: Dictionary source type
            include_unmapped: Include unmapped tokens

        Returns:
            Dictionary details
        """
        try:
            from dss.translations.loader import TranslationDictionaryLoader

            project_path = await self._get_project_path(project_id)
            loader = TranslationDictionaryLoader(str(project_path))

            dictionary = await loader.load_dictionary(source)
            if not dictionary:
                available = [f.stem for f in loader.translations_dir.glob("*.json")] if loader.translations_dir.exists() else []
                return {
                    "error": f"Dictionary not found: {source}",
                    "project_id": project_id,
                    "available": available
                }

            result = {
                "project_id": project_id,
                "source": source,
                "uuid": str(dictionary.uuid),
                "version": dictionary.version,
                "created_at": dictionary.created_at.isoformat() if hasattr(dictionary.created_at, 'isoformat') else str(dictionary.created_at),
                "updated_at": dictionary.updated_at.isoformat() if hasattr(dictionary.updated_at, 'isoformat') else str(dictionary.updated_at),
                "mappings": {
                    "tokens": dictionary.mappings.tokens,
                    "components": dictionary.mappings.components,
                    "patterns": dictionary.mappings.patterns
                },
                "custom_props": dictionary.custom_props,
                "notes": dictionary.notes or []
            }

            if include_unmapped:
                result["unmapped"] = dictionary.unmapped

            return result

        except Exception as e:
            return {
                "error": f"Failed to get dictionary: {str(e)}",
                "project_id": project_id,
                "source": source
            }

    async def create_dictionary(
        self,
        project_id: str,
        source: str,
        token_mappings: Optional[Dict[str, str]] = None,
        component_mappings: Optional[Dict[str, str]] = None,
        custom_props: Optional[Dict[str, Any]] = None,
        notes: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Create new translation dictionary.

        Args:
            project_id: Project ID
            source: Source type
            token_mappings: Token mappings
            component_mappings: Component mappings
            custom_props: Custom properties
            notes: Notes

        Returns:
            Creation result
        """
        try:
            from dss.translations.writer import TranslationDictionaryWriter
            from dss.translations.validator import TranslationValidator

            project_path = await self._get_project_path(project_id)
            writer = TranslationDictionaryWriter(str(project_path))

            # Validate before creating
            validator = TranslationValidator()
            test_data = {
                "$schema": "dss-translation-v1",
                "project": project_id,
                "source": source,
                "mappings": {
                    "tokens": token_mappings or {},
                    "components": component_mappings or {}
                },
                "custom_props": custom_props or {}
            }

            validation_result = validator.validate_dictionary(test_data)
            if not validation_result.is_valid:
                return {
                    "error": "Validation failed",
                    "errors": [str(e) for e in validation_result.errors],
                    "warnings": [str(w) for w in validation_result.warnings]
                }

            # Create the dictionary
            dictionary = await writer.create(
                source=source,
                project=project_id,
                token_mappings=token_mappings,
                component_mappings=component_mappings,
                custom_props=custom_props,
                notes=notes
            )

            return {
                "project_id": project_id,
                "source": source,
                "uuid": str(dictionary.uuid),
                "created": True,
                "file_path": str(writer.translations_dir / f"{source}.json"),
                "token_count": len(dictionary.mappings.tokens),
                "component_count": len(dictionary.mappings.components),
                "custom_prop_count": len(dictionary.custom_props),
                "warnings": [str(w) for w in validation_result.warnings] if validation_result.warnings else []
            }

        except Exception as e:
            return {
                "error": f"Failed to create dictionary: {str(e)}",
                "project_id": project_id,
                "source": source
            }

    async def update_dictionary(
        self,
        project_id: str,
        source: str,
        token_mappings: Optional[Dict[str, str]] = None,
        component_mappings: Optional[Dict[str, str]] = None,
        custom_props: Optional[Dict[str, Any]] = None,
        remove_tokens: Optional[List[str]] = None,
        notes: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Update existing translation dictionary.

        Args:
            project_id: Project ID
            source: Source type
            token_mappings: Token mappings to add/update
            component_mappings: Component mappings to add/update
            custom_props: Custom props to add/update
            remove_tokens: Tokens to remove
            notes: Notes to append

        Returns:
            Update result
        """
        try:
            from dss.translations.loader import TranslationDictionaryLoader
            from dss.translations.writer import TranslationDictionaryWriter

            project_path = await self._get_project_path(project_id)
            loader = TranslationDictionaryLoader(str(project_path))
            writer = TranslationDictionaryWriter(str(project_path))

            # Load existing dictionary
            existing = await loader.load_dictionary(source)
            if not existing:
                return {
                    "error": f"Dictionary not found: {source}",
                    "project_id": project_id
                }

            # Merge updates
            updated_tokens = dict(existing.mappings.tokens)
            if token_mappings:
                updated_tokens.update(token_mappings)
            if remove_tokens:
                for token in remove_tokens:
                    updated_tokens.pop(token, None)

            updated_components = dict(existing.mappings.components)
            if component_mappings:
                updated_components.update(component_mappings)

            updated_custom = dict(existing.custom_props)
            if custom_props:
                updated_custom.update(custom_props)

            updated_notes = list(existing.notes or [])
            if notes:
                updated_notes.extend(notes)

            # Write updated dictionary
            dictionary = await writer.create(
                source=source,
                project=project_id,
                token_mappings=updated_tokens,
                component_mappings=updated_components,
                custom_props=updated_custom,
                notes=updated_notes
            )

            return {
                "project_id": project_id,
                "source": source,
                "uuid": str(dictionary.uuid),
                "updated": True,
                "file_path": str(writer.translations_dir / f"{source}.json"),
                "token_count": len(dictionary.mappings.tokens),
                "component_count": len(dictionary.mappings.components),
                "custom_prop_count": len(dictionary.custom_props),
                "notes_count": len(dictionary.notes or [])
            }

        except Exception as e:
            return {
                "error": f"Failed to update dictionary: {str(e)}",
                "project_id": project_id,
                "source": source
            }

    async def validate_dictionary(
        self,
        project_id: str,
        source: str,
        strict: bool = False
    ) -> Dict[str, Any]:
        """
        Validate a translation dictionary.

        Args:
            project_id: Project ID
            source: Source type
            strict: Strict validation mode

        Returns:
            Validation result
        """
        try:
            from dss.translations.loader import TranslationDictionaryLoader
            from dss.translations.validator import TranslationValidator

            project_path = await self._get_project_path(project_id)
            loader = TranslationDictionaryLoader(str(project_path))

            dictionary = await loader.load_dictionary(source)
            if not dictionary:
                return {
                    "error": f"Dictionary not found: {source}",
                    "project_id": project_id,
                    "valid": False
                }

            validator = TranslationValidator()

            # Convert dictionary to dict for validation
            dict_data = {
                "$schema": "dss-translation-v1",
                "uuid": str(dictionary.uuid),
                "project": project_id,
                "source": source,
                "version": dictionary.version,
                "created_at": dictionary.created_at.isoformat() if hasattr(dictionary.created_at, 'isoformat') else str(dictionary.created_at),
                "updated_at": dictionary.updated_at.isoformat() if hasattr(dictionary.updated_at, 'isoformat') else str(dictionary.updated_at),
                "mappings": {
                    "tokens": dictionary.mappings.tokens,
                    "components": dictionary.mappings.components,
                    "patterns": dictionary.mappings.patterns
                },
                "custom_props": dictionary.custom_props,
                "unmapped": dictionary.unmapped,
                "notes": dictionary.notes or []
            }

            result = validator.validate_dictionary(dict_data, strict=strict)

            return {
                "project_id": project_id,
                "source": source,
                "valid": result.is_valid,
                "errors": [str(e) for e in (result.errors or [])],
                "warnings": [str(w) for w in (result.warnings or [])]
            }

        except Exception as e:
            return {
                "error": f"Failed to validate dictionary: {str(e)}",
                "project_id": project_id,
                "source": source,
                "valid": False
            }

    # =========================================================================
    # Category 2: Theme Configuration
    # =========================================================================

    async def get_config(self, project_id: str) -> Dict[str, Any]:
        """
        Get project theme configuration.

        Args:
            project_id: Project ID

        Returns:
            Theme configuration
        """
        try:
            from dss.translations.loader import TranslationDictionaryLoader

            project_path = await self._get_project_path(project_id)
            loader = TranslationDictionaryLoader(str(project_path))

            # Load registry to get full picture
            registry = await loader.load_all()

            return {
                "project_id": project_id,
                "base_themes_available": ["light", "dark"],
                "translation_dictionaries": list(registry.dictionaries.keys()),
                "total_token_mappings": len(registry.combined_token_map),
                "total_component_mappings": len(registry.combined_component_map),
                "total_custom_props": len(registry.all_custom_props),
                "conflicts": registry.conflicts,
                "has_config": loader.has_translations()
            }

        except Exception as e:
            return {
                "error": f"Failed to get config: {str(e)}",
                "project_id": project_id
            }

    async def resolve_theme(
        self,
        project_id: str,
        base_theme: str = "light",
        include_provenance: bool = False
    ) -> Dict[str, Any]:
        """
        Resolve complete project theme.

        Args:
            project_id: Project ID
            base_theme: Base theme (light or dark)
            include_provenance: Include provenance information

        Returns:
            Resolved theme with tokens
        """
        try:
            from dss.translations.loader import TranslationDictionaryLoader
            from dss.translations.merger import ThemeMerger

            project_path = await self._get_project_path(project_id)

            # Load translation registry
            loader = TranslationDictionaryLoader(str(project_path))
            registry = await loader.load_all()

            # Create merger and resolve
            merger = ThemeMerger(registry)
            resolved = await merger.merge(
                base_theme=base_theme,
                project_name=project_id
            )

            # Format tokens for output
            tokens = {}
            for dss_path, resolved_token in resolved.tokens.items():
                token_data = {
                    "value": str(resolved_token.value),
                    "source_token": resolved_token.source_token,
                    "is_custom": resolved_token.is_custom
                }
                if include_provenance and hasattr(resolved_token, 'provenance'):
                    token_data["provenance"] = resolved_token.provenance
                tokens[dss_path] = token_data

            custom_props = {}
            for dss_path, resolved_token in resolved.custom_props.items():
                prop_data = {
                    "value": str(resolved_token.value)
                }
                if include_provenance and hasattr(resolved_token, 'provenance'):
                    prop_data["provenance"] = resolved_token.provenance
                custom_props[dss_path] = prop_data

            return {
                "project_id": project_id,
                "name": resolved.name,
                "base_theme": resolved.base_theme,
                "version": resolved.version,
                "resolved_at": resolved.resolved_at.isoformat() if hasattr(resolved.resolved_at, 'isoformat') else str(resolved.resolved_at),
                "translations_applied": resolved.translations_applied,
                "token_count": len(tokens),
                "custom_prop_count": len(custom_props),
                "tokens": tokens,
                "custom_props": custom_props
            }

        except Exception as e:
            return {
                "error": f"Failed to resolve theme: {str(e)}",
                "project_id": project_id
            }

    async def add_custom_prop(
        self,
        project_id: str,
        prop_name: str,
        prop_value: Any,
        description: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        Add custom property to custom.json.

        Args:
            project_id: Project ID
            prop_name: Property name (DSS namespace)
            prop_value: Property value
            description: Optional description

        Returns:
            Update result
        """
        try:
            from dss.translations.loader import TranslationDictionaryLoader
            from dss.translations.writer import TranslationDictionaryWriter

            project_path = await self._get_project_path(project_id)
            loader = TranslationDictionaryLoader(str(project_path))
            writer = TranslationDictionaryWriter(str(project_path))

            # Load or create custom dictionary
            custom_dict = await loader.load_dictionary("custom")
            if custom_dict:
                custom_props = dict(custom_dict.custom_props)
            else:
                custom_props = {}

            # Add new property
            custom_props[prop_name] = prop_value

            # Write updated custom dictionary
            dictionary = await writer.create(
                source="custom",
                project=project_id,
                custom_props=custom_props,
                notes=[f"Added {prop_name}"] if not description else [description]
            )

            return {
                "project_id": project_id,
                "prop_name": prop_name,
                "prop_value": prop_value,
                "added": True,
                "custom_prop_count": len(dictionary.custom_props)
            }

        except Exception as e:
            return {
                "error": f"Failed to add custom prop: {str(e)}",
                "project_id": project_id,
                "prop_name": prop_name
            }

    async def get_canonical_tokens(
        self,
        category: Optional[str] = None,
        include_aliases: bool = True,
        include_components: bool = False
    ) -> Dict[str, Any]:
        """
        Get DSS canonical token structure.

        Args:
            category: Filter by category
            include_aliases: Include aliases
            include_components: Include components

        Returns:
            Canonical token structure
        """
        try:
            from dss.translations.canonical import (
                DSS_CANONICAL_TOKENS,
                DSS_TOKEN_ALIASES,
                DSS_CANONICAL_COMPONENTS,
                get_canonical_token_categories
            )

            result = {
                "total_tokens": len(DSS_CANONICAL_TOKENS)
            }

            if category:
                # Filter by category
                categories = get_canonical_token_categories()
                result["category"] = category
                result["tokens"] = categories.get(category, [])
                result["token_count"] = len(categories.get(category, []))
            else:
                # Return all organized by category
                categories = get_canonical_token_categories()
                result["tokens_by_category"] = {k: list(v) for k, v in categories.items()}

            if include_aliases:
                result["aliases"] = DSS_TOKEN_ALIASES

            if include_components:
                result["components"] = list(DSS_CANONICAL_COMPONENTS)
                result["component_count"] = len(DSS_CANONICAL_COMPONENTS)

            return result

        except Exception as e:
            return {
                "error": f"Failed to get canonical tokens: {str(e)}"
            }

    # =========================================================================
    # Category 3: Code Generation
    # =========================================================================

    async def export_css(
        self,
        project_id: str,
        base_theme: str = "light",
        selector: str = ":root",
        prefix: str = "dss",
        include_comments: bool = True,
        output_path: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        Generate CSS variables from resolved theme.

        Args:
            project_id: Project ID
            base_theme: Base theme
            selector: CSS selector
            prefix: CSS variable prefix
            include_comments: Include comments
            output_path: Optional output file path

        Returns:
            CSS export result
        """
        try:
            # Resolve theme first
            resolved_result = await self.resolve_theme(
                project_id,
                base_theme,
                include_provenance=include_comments
            )

            if "error" in resolved_result:
                return resolved_result

            # Generate CSS
            css_lines = []
            if include_comments:
                css_lines.append(f"/* DSS Theme: {resolved_result['name']} */")
                css_lines.append(f"/* Base: {base_theme} | Generated: {resolved_result['resolved_at']} */")
                css_lines.append(f"/* Translations: {', '.join(resolved_result['translations_applied'])} */")
                css_lines.append("")

            css_lines.append(f"{selector} {{")

            # Core tokens
            for dss_path, token_data in resolved_result["tokens"].items():
                var_name = f"--{prefix}-{dss_path.replace('.', '-')}"
                value = token_data["value"]

                if include_comments and token_data.get("source_token"):
                    css_lines.append(f"  /* Source: {token_data['source_token']} */")

                css_lines.append(f"  {var_name}: {value};")

            # Custom props
            if resolved_result["custom_props"]:
                css_lines.append("")
                css_lines.append("  /* Custom Properties */")
                for dss_path, prop_data in resolved_result["custom_props"].items():
                    var_name = f"--{prefix}-{dss_path.replace('.', '-')}"
                    css_lines.append(f"  {var_name}: {prop_data['value']};")

            css_lines.append("}")

            css_content = "\n".join(css_lines)

            if output_path:
                project_path = await self._get_project_path(project_id)
                full_path = (project_path / output_path).resolve()

                # Validate path is within project directory (prevent traversal)
                try:
                    full_path.relative_to(project_path)
                except ValueError:
                    return {
                        "error": "Output path must be within project directory",
                        "project_id": project_id
                    }

                full_path.parent.mkdir(parents=True, exist_ok=True)
                # Use asyncio.to_thread to avoid blocking event loop
                await asyncio.to_thread(full_path.write_text, css_content)

                return {
                    "project_id": project_id,
                    "output_path": str(full_path),
                    "written": True,
                    "token_count": resolved_result["token_count"],
                    "custom_prop_count": resolved_result["custom_prop_count"]
                }

            return {
                "project_id": project_id,
                "content": css_content,
                "token_count": resolved_result["token_count"],
                "custom_prop_count": resolved_result["custom_prop_count"]
            }

        except Exception as e:
            return {
                "error": f"Failed to export CSS: {str(e)}",
                "project_id": project_id
            }

    async def export_scss(
        self,
        project_id: str,
        base_theme: str = "light",
        prefix: str = "dss",
        generate_map: bool = True,
        output_path: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        Generate SCSS variables from resolved theme.

        Args:
            project_id: Project ID
            base_theme: Base theme
            prefix: SCSS variable prefix
            generate_map: Generate SCSS map
            output_path: Optional output file path

        Returns:
            SCSS export result
        """
        try:
            # Resolve theme first
            resolved_result = await self.resolve_theme(project_id, base_theme, include_provenance=False)

            if "error" in resolved_result:
                return resolved_result

            # Generate SCSS
            scss_lines = []
            scss_lines.append(f"// DSS Theme: {resolved_result['name']}")
            scss_lines.append(f"// Base: {base_theme} | Generated: {resolved_result['resolved_at']}")
            scss_lines.append(f"// Translations: {', '.join(resolved_result['translations_applied'])}")
            scss_lines.append("")

            # Variables
            for dss_path, token_data in resolved_result["tokens"].items():
                var_name = f"${prefix}-{dss_path.replace('.', '-')}"
                value = token_data["value"]
                scss_lines.append(f"{var_name}: {value};")

            # Custom props
            if resolved_result["custom_props"]:
                scss_lines.append("")
                for dss_path, prop_data in resolved_result["custom_props"].items():
                    var_name = f"${prefix}-{dss_path.replace('.', '-')}"
                    scss_lines.append(f"{var_name}: {prop_data['value']};")

            # Generate map if requested
            if generate_map:
                scss_lines.append("")
                scss_lines.append(f"${prefix}-tokens: (")

                # Add all tokens to map
                token_list = list(resolved_result["tokens"].items())
                for i, (dss_path, token_data) in enumerate(token_list):
                    key = dss_path.replace('.', '-')
                    value = token_data["value"]
                    comma = "," if i < len(token_list) - 1 else ""
                    scss_lines.append(f'  "{key}": {value}{comma}')

                # Add custom props to map
                custom_list = list(resolved_result["custom_props"].items())
                if custom_list and token_list:
                    scss_lines[-1] = scss_lines[-1] + ","
                for i, (dss_path, prop_data) in enumerate(custom_list):
                    key = dss_path.replace('.', '-')
                    value = prop_data["value"]
                    comma = "," if i < len(custom_list) - 1 else ""
                    scss_lines.append(f'  "{key}": {value}{comma}')

                scss_lines.append(");")

            scss_content = "\n".join(scss_lines)

            if output_path:
                project_path = await self._get_project_path(project_id)
                full_path = (project_path / output_path).resolve()

                # Validate path is within project directory (prevent traversal)
                try:
                    full_path.relative_to(project_path)
                except ValueError:
                    return {
                        "error": "Output path must be within project directory",
                        "project_id": project_id
                    }

                full_path.parent.mkdir(parents=True, exist_ok=True)
                # Use asyncio.to_thread to avoid blocking event loop
                await asyncio.to_thread(full_path.write_text, scss_content)

                return {
                    "project_id": project_id,
                    "output_path": str(full_path),
                    "written": True,
                    "token_count": resolved_result["token_count"],
                    "custom_prop_count": resolved_result["custom_prop_count"]
                }

            return {
                "project_id": project_id,
                "content": scss_content,
                "token_count": resolved_result["token_count"],
                "custom_prop_count": resolved_result["custom_prop_count"]
            }

        except Exception as e:
            return {
                "error": f"Failed to export SCSS: {str(e)}",
                "project_id": project_id
            }

    async def export_json(
        self,
        project_id: str,
        base_theme: str = "light",
        format: str = "flat",
        include_metadata: bool = True,
        output_path: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        Export resolved theme as JSON.

        Args:
            project_id: Project ID
            base_theme: Base theme
            format: JSON format (flat, nested, style-dictionary)
            include_metadata: Include metadata
            output_path: Optional output file path

        Returns:
            JSON export result
        """
        try:
            # Resolve theme first
            resolved_result = await self.resolve_theme(project_id, base_theme, include_provenance=False)

            if "error" in resolved_result:
                return resolved_result

            # Build JSON structure based on format
            if format == "nested":
                # Nested format: organize by category
                json_data = self._build_nested_tokens(resolved_result)
            elif format == "style-dictionary":
                # Style Dictionary format
                json_data = self._build_style_dictionary_tokens(resolved_result)
            else:
                # Flat format (default)
                json_data = {
                    "tokens": resolved_result["tokens"],
                    "customProps": resolved_result["custom_props"]
                }

            if include_metadata:
                json_data["metadata"] = {
                    "project_id": project_id,
                    "base_theme": base_theme,
                    "generated_at": resolved_result["resolved_at"],
                    "token_count": resolved_result["token_count"],
                    "custom_prop_count": resolved_result["custom_prop_count"],
                    "translations": resolved_result["translations_applied"]
                }

            json_content = json.dumps(json_data, indent=2)

            if output_path:
                project_path = await self._get_project_path(project_id)
                full_path = (project_path / output_path).resolve()

                # Validate path is within project directory (prevent traversal)
                try:
                    full_path.relative_to(project_path)
                except ValueError:
                    return {
                        "error": "Output path must be within project directory",
                        "project_id": project_id
                    }

                full_path.parent.mkdir(parents=True, exist_ok=True)
                # Use asyncio.to_thread to avoid blocking event loop
                await asyncio.to_thread(full_path.write_text, json_content)

                return {
                    "project_id": project_id,
                    "output_path": str(full_path),
                    "written": True,
                    "token_count": resolved_result["token_count"],
                    "custom_prop_count": resolved_result["custom_prop_count"]
                }

            return {
                "project_id": project_id,
                "content": json_data,
                "token_count": resolved_result["token_count"],
                "custom_prop_count": resolved_result["custom_prop_count"]
            }

        except Exception as e:
            return {
                "error": f"Failed to export JSON: {str(e)}",
                "project_id": project_id
            }

    def _build_nested_tokens(self, resolved_result: Dict[str, Any]) -> Dict[str, Any]:
        """Build nested token structure from flat tokens."""
        nested = {}

        for dss_path, token_data in resolved_result["tokens"].items():
            parts = dss_path.split('.')
            current = nested
            for part in parts[:-1]:
                if part not in current:
                    current[part] = {}
                current = current[part]
            current[parts[-1]] = token_data["value"]

        # Add custom props
        if "customProps" not in nested:
            nested["customProps"] = {}
        for dss_path, prop_data in resolved_result["custom_props"].items():
            parts = dss_path.split('.')
            current = nested["customProps"]
            for part in parts[:-1]:
                if part not in current:
                    current[part] = {}
                current = current[part]
            current[parts[-1]] = prop_data["value"]

        return nested

    def _build_style_dictionary_tokens(self, resolved_result: Dict[str, Any]) -> Dict[str, Any]:
        """Build Style Dictionary format from flat tokens."""
        style_dict = {}

        for dss_path, token_data in resolved_result["tokens"].items():
            parts = dss_path.split('.')
            current = style_dict
            for part in parts[:-1]:
                if part not in current:
                    current[part] = {}
                current = current[part]
            current[parts[-1]] = {
                "value": token_data["value"],
                "type": self._infer_token_type(dss_path),
                "description": f"DSS token {dss_path}"
            }

        # Add custom props
        if "custom" not in style_dict:
            style_dict["custom"] = {}
        for dss_path, prop_data in resolved_result["custom_props"].items():
            parts = dss_path.split('.')
            current = style_dict["custom"]
            for part in parts[:-1]:
                if part not in current:
                    current[part] = {}
                current = current[part]
            current[parts[-1]] = {
                "value": prop_data["value"],
                "type": "custom",
                "description": f"Custom token {dss_path}"
            }

        return style_dict

    def _infer_token_type(self, token_path: str) -> str:
        """Infer token type from path."""
        if token_path.startswith("color"):
            return "color"
        elif token_path.startswith("spacing"):
            return "dimension"
        elif token_path.startswith("typography"):
            return "typography"
        elif token_path.startswith("border"):
            return "border"
        elif token_path.startswith("shadow"):
            return "shadow"
        else:
            return "string"


# =============================================================================
# MCP Tool Executor
# =============================================================================

class TranslationTools:
    """MCP tool executor for translation integration"""

    def __init__(self, config: Optional[Dict[str, Any]] = None):
        """
        Initialize Translation tools.

        Args:
            config: Optional configuration
        """
        self.translations = TranslationIntegration(config)

    async def execute_tool(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
        """
        Execute translation tool.

        Args:
            tool_name: Name of tool to execute
            arguments: Tool arguments

        Returns:
            Tool execution result
        """
        handlers = {
            # Category 1
            "translation_list_dictionaries": self.translations.list_dictionaries,
            "translation_get_dictionary": self.translations.get_dictionary,
            "translation_create_dictionary": self.translations.create_dictionary,
            "translation_update_dictionary": self.translations.update_dictionary,
            "translation_validate_dictionary": self.translations.validate_dictionary,
            # Category 2
            "theme_get_config": self.translations.get_config,
            "theme_resolve": self.translations.resolve_theme,
            "theme_add_custom_prop": self.translations.add_custom_prop,
            "theme_get_canonical_tokens": self.translations.get_canonical_tokens,
            # Category 3
            "codegen_export_css": self.translations.export_css,
            "codegen_export_scss": self.translations.export_scss,
            "codegen_export_json": self.translations.export_json,
        }

        handler = handlers.get(tool_name)
        if not handler:
            return {"error": f"Unknown translation tool: {tool_name}"}

        try:
            # Remove internal prefixes and execute
            clean_args = {k: v for k, v in arguments.items() if not k.startswith("_")}
            return await handler(**clean_args)
        except Exception as e:
            return {"error": f"Tool execution failed: {str(e)}", "tool": tool_name}
