"""
DSS Project Tools for MCP

Base tools that Claude can use to interact with DSS projects.
All tools are project-scoped and context-aware.
"""

from typing import Dict, Any, List, Optional
from mcp import types

from ..context.project_context import get_context_manager


# Tool definitions (metadata for Claude)
PROJECT_TOOLS = [
    types.Tool(
        name="dss_get_project_summary",
        description="Get comprehensive project summary including components, tokens, health, and stats",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID to query"
                },
                "include_components": {
                    "type": "boolean",
                    "description": "Include full component list (default: false)",
                    "default": False
                }
            },
            "required": ["project_id"]
        }
    ),
    types.Tool(
        name="dss_list_components",
        description="List all components in a project with their properties",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "filter_name": {
                    "type": "string",
                    "description": "Optional: Filter by component name (partial match)"
                },
                "code_generated_only": {
                    "type": "boolean",
                    "description": "Optional: Only show components with generated code",
                    "default": False
                }
            },
            "required": ["project_id"]
        }
    ),
    types.Tool(
        name="dss_get_component",
        description="Get detailed information about a specific component",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "component_name": {
                    "type": "string",
                    "description": "Component name (exact match)"
                }
            },
            "required": ["project_id", "component_name"]
        }
    ),
    types.Tool(
        name="dss_get_design_tokens",
        description="Get all design tokens (colors, typography, spacing, etc.) for a project",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "token_category": {
                    "type": "string",
                    "description": "Optional: Filter by token category (colors, typography, spacing, etc.)",
                    "enum": ["colors", "typography", "spacing", "shadows", "borders", "all"]
                }
            },
            "required": ["project_id"]
        }
    ),
    types.Tool(
        name="dss_get_project_health",
        description="Get project health score, grade, and list of issues",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                }
            },
            "required": ["project_id"]
        }
    ),
    types.Tool(
        name="dss_list_styles",
        description="List design styles (text, fill, effect, grid) from Figma",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                },
                "style_type": {
                    "type": "string",
                    "description": "Optional: Filter by style type",
                    "enum": ["TEXT", "FILL", "EFFECT", "GRID", "all"]
                }
            },
            "required": ["project_id"]
        }
    ),
    types.Tool(
        name="dss_get_discovery_data",
        description="Get project discovery/scan data (file counts, technologies detected, etc.)",
        inputSchema={
            "type": "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "description": "Project ID"
                }
            },
            "required": ["project_id"]
        }
    )
]


# Tool implementations
class ProjectTools:
    """Project tool implementations"""

    def __init__(self, user_id: Optional[int] = None):
        self.context_manager = get_context_manager()
        self.user_id = user_id

    async def execute_tool(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
        """Execute a tool by name"""
        handlers = {
            "dss_get_project_summary": self.get_project_summary,
            "dss_list_components": self.list_components,
            "dss_get_component": self.get_component,
            "dss_get_design_tokens": self.get_design_tokens,
            "dss_get_project_health": self.get_project_health,
            "dss_list_styles": self.list_styles,
            "dss_get_discovery_data": self.get_discovery_data
        }

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

        try:
            result = await handler(**arguments)
            return result
        except Exception as e:
            return {"error": str(e)}

    async def get_project_summary(
        self,
        project_id: str,
        include_components: bool = False
    ) -> Dict[str, Any]:
        """Get comprehensive project summary"""
        context = await self.context_manager.get_context(project_id, self.user_id)
        if not context:
            return {"error": f"Project not found: {project_id}"}

        summary = {
            "project_id": context.project_id,
            "name": context.name,
            "description": context.description,
            "component_count": context.component_count,
            "health": context.health,
            "stats": context.stats,
            "config": context.config,
            "integrations_enabled": list(context.integrations.keys()),
            "loaded_at": context.loaded_at.isoformat()
        }

        if include_components:
            summary["components"] = context.components

        return summary

    async def list_components(
        self,
        project_id: str,
        filter_name: Optional[str] = None,
        code_generated_only: bool = False
    ) -> Dict[str, Any]:
        """List components with optional filtering"""
        context = await self.context_manager.get_context(project_id, self.user_id)
        if not context:
            return {"error": f"Project not found: {project_id}"}

        components = context.components

        # Apply filters
        if filter_name:
            components = [
                c for c in components
                if filter_name.lower() in c['name'].lower()
            ]

        if code_generated_only:
            components = [c for c in components if c.get('code_generated')]

        return {
            "project_id": project_id,
            "total_count": len(components),
            "components": components
        }

    async def get_component(
        self,
        project_id: str,
        component_name: str
    ) -> Dict[str, Any]:
        """Get detailed component information"""
        context = await self.context_manager.get_context(project_id, self.user_id)
        if not context:
            return {"error": f"Project not found: {project_id}"}

        # Find component by name
        component = next(
            (c for c in context.components if c['name'] == component_name),
            None
        )

        if not component:
            return {"error": f"Component not found: {component_name}"}

        return {
            "project_id": project_id,
            "component": component
        }

    async def get_design_tokens(
        self,
        project_id: str,
        token_category: Optional[str] = None
    ) -> Dict[str, Any]:
        """Get design tokens, optionally filtered by category"""
        context = await self.context_manager.get_context(project_id, self.user_id)
        if not context:
            return {"error": f"Project not found: {project_id}"}

        tokens = context.tokens

        if token_category and token_category != "all":
            # Filter by category
            if token_category in tokens:
                tokens = {token_category: tokens[token_category]}
            else:
                tokens = {}

        return {
            "project_id": project_id,
            "tokens": tokens,
            "categories": list(tokens.keys())
        }

    async def get_project_health(self, project_id: str) -> Dict[str, Any]:
        """Get project health information"""
        context = await self.context_manager.get_context(project_id, self.user_id)
        if not context:
            return {"error": f"Project not found: {project_id}"}

        return {
            "project_id": project_id,
            "health": context.health
        }

    async def list_styles(
        self,
        project_id: str,
        style_type: Optional[str] = None
    ) -> Dict[str, Any]:
        """List design styles with optional type filter"""
        context = await self.context_manager.get_context(project_id, self.user_id)
        if not context:
            return {"error": f"Project not found: {project_id}"}

        styles = context.styles

        if style_type and style_type != "all":
            styles = [s for s in styles if s['type'] == style_type]

        return {
            "project_id": project_id,
            "total_count": len(styles),
            "styles": styles
        }

    async def get_discovery_data(self, project_id: str) -> Dict[str, Any]:
        """Get project discovery/scan data"""
        context = await self.context_manager.get_context(project_id, self.user_id)
        if not context:
            return {"error": f"Project not found: {project_id}"}

        return {
            "project_id": project_id,
            "discovery": context.discovery
        }
