"""MCP Server for ccontext."""

import json
from pathlib import Path
from typing import Any

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent

from .tools import ContextTools, TOOL_DESCRIPTIONS


def create_server() -> Server:
    """Create and configure the MCP server."""
    server = Server("ccontext-mcp")
    tools = ContextTools(Path.cwd())

    @server.list_tools()
    async def list_tools() -> list[Tool]:
        """List all available tools."""
        return [
            # Context
            Tool(
                name="get_context",
                description=TOOL_DESCRIPTIONS["get_context"],
                inputSchema={
                    "type": "object",
                    "properties": {},
                    "required": [],
                },
            ),
            # Milestone tools
            Tool(
                name="create_milestone",
                description=TOOL_DESCRIPTIONS["create_milestone"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "name": {"type": "string", "description": "Milestone name/goal"},
                        "description": {"type": "string", "description": "Detailed description"},
                        "status": {
                            "type": "string",
                            "enum": ["pending", "active", "done"],
                            "default": "pending",
                            "description": "Initial status",
                        },
                    },
                    "required": ["name", "description"],
                },
            ),
            Tool(
                name="update_milestone",
                description=TOOL_DESCRIPTIONS["update_milestone"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "milestone_id": {"type": "string", "description": "Milestone ID (M1, M2...)"},
                        "name": {"type": "string", "description": "New name"},
                        "description": {"type": "string", "description": "New description"},
                        "status": {
                            "type": "string",
                            "enum": ["pending", "active", "done"],
                            "description": "New status",
                        },
                    },
                    "required": ["milestone_id"],
                },
            ),
            Tool(
                name="complete_milestone",
                description=TOOL_DESCRIPTIONS["complete_milestone"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "milestone_id": {"type": "string", "description": "Milestone ID"},
                        "outcomes": {"type": "string", "description": "Results summary"},
                    },
                    "required": ["milestone_id", "outcomes"],
                },
            ),
            Tool(
                name="remove_milestone",
                description=TOOL_DESCRIPTIONS["remove_milestone"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "milestone_id": {"type": "string", "description": "Milestone ID to remove"},
                    },
                    "required": ["milestone_id"],
                },
            ),
            # Task tools
            Tool(
                name="list_tasks",
                description=TOOL_DESCRIPTIONS["list_tasks"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "task_id": {"type": "string", "description": "Get specific task by ID"},
                        "status": {
                            "type": "string",
                            "enum": ["planned", "active", "done"],
                            "description": "Filter by status",
                        },
                        "assignee": {"type": "string", "description": "Filter by assignee"},
                        "include_archived": {
                            "type": "boolean",
                            "default": False,
                            "description": "Include archived tasks",
                        },
                    },
                    "required": [],
                },
            ),
            Tool(
                name="create_task",
                description=TOOL_DESCRIPTIONS["create_task"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "name": {"type": "string", "description": "Task name"},
                        "goal": {"type": "string", "description": "Completion criteria"},
                        "steps": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "name": {"type": "string"},
                                    "done": {"type": "string"},
                                },
                                "required": ["name", "done"],
                            },
                            "description": "List of steps",
                        },
                        "task_id": {"type": "string", "description": "Custom task ID (optional)"},
                        "assignee": {"type": "string", "description": "Assignee"},
                    },
                    "required": ["name", "goal", "steps"],
                },
            ),
            Tool(
                name="update_task",
                description=TOOL_DESCRIPTIONS["update_task"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "task_id": {"type": "string", "description": "Task ID to update"},
                        "status": {
                            "type": "string",
                            "enum": ["planned", "active", "done"],
                            "description": "New status",
                        },
                        "name": {"type": "string", "description": "New name"},
                        "goal": {"type": "string", "description": "New goal"},
                        "assignee": {"type": "string", "description": "New assignee"},
                        "step_id": {"type": "string", "description": "Step ID to update"},
                        "step_status": {
                            "type": "string",
                            "enum": ["pending", "in_progress", "done"],
                            "description": "New step status",
                        },
                    },
                    "required": ["task_id"],
                },
            ),
            Tool(
                name="delete_task",
                description=TOOL_DESCRIPTIONS["delete_task"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "task_id": {"type": "string", "description": "Task ID to delete"},
                    },
                    "required": ["task_id"],
                },
            ),
            # Note tools
            Tool(
                name="add_note",
                description=TOOL_DESCRIPTIONS["add_note"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "content": {"type": "string", "description": "Note content"},
                        "score": {
                            "type": "integer",
                            "minimum": 10,
                            "maximum": 100,
                            "default": 15,
                            "description": "Initial score (10-100, higher = persists longer)",
                        },
                    },
                    "required": ["content"],
                },
            ),
            Tool(
                name="update_note",
                description=TOOL_DESCRIPTIONS["update_note"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "note_id": {"type": "string", "description": "Note ID (N001, N002...)"},
                        "content": {"type": "string", "description": "New content"},
                        "score": {
                            "type": "integer",
                            "minimum": 10,
                            "maximum": 100,
                            "description": "New score",
                        },
                    },
                    "required": ["note_id"],
                },
            ),
            Tool(
                name="remove_note",
                description=TOOL_DESCRIPTIONS["remove_note"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "note_id": {"type": "string", "description": "Note ID to remove"},
                    },
                    "required": ["note_id"],
                },
            ),
            # Reference tools
            Tool(
                name="add_reference",
                description=TOOL_DESCRIPTIONS["add_reference"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "url": {"type": "string", "description": "File path or URL"},
                        "note": {"type": "string", "description": "Description"},
                        "score": {
                            "type": "integer",
                            "minimum": 10,
                            "maximum": 100,
                            "default": 15,
                            "description": "Initial score (10-100)",
                        },
                    },
                    "required": ["url", "note"],
                },
            ),
            Tool(
                name="update_reference",
                description=TOOL_DESCRIPTIONS["update_reference"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "reference_id": {"type": "string", "description": "Reference ID (R001...)"},
                        "url": {"type": "string", "description": "New URL"},
                        "note": {"type": "string", "description": "New description"},
                        "score": {
                            "type": "integer",
                            "minimum": 10,
                            "maximum": 100,
                            "description": "New score",
                        },
                    },
                    "required": ["reference_id"],
                },
            ),
            Tool(
                name="remove_reference",
                description=TOOL_DESCRIPTIONS["remove_reference"],
                inputSchema={
                    "type": "object",
                    "properties": {
                        "reference_id": {"type": "string", "description": "Reference ID to remove"},
                    },
                    "required": ["reference_id"],
                },
            ),
        ]

    @server.call_tool()
    async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
        """Handle tool calls."""
        try:
            # Context
            if name == "get_context":
                result = tools.get_context()

            # Milestone tools
            elif name == "create_milestone":
                result = tools.create_milestone(
                    name=arguments["name"],
                    description=arguments["description"],
                    status=arguments.get("status", "pending"),
                )
            elif name == "update_milestone":
                result = tools.update_milestone(
                    milestone_id=arguments["milestone_id"],
                    name=arguments.get("name"),
                    description=arguments.get("description"),
                    status=arguments.get("status"),
                )
            elif name == "complete_milestone":
                result = tools.complete_milestone(
                    milestone_id=arguments["milestone_id"],
                    outcomes=arguments["outcomes"],
                )
            elif name == "remove_milestone":
                result = tools.remove_milestone(milestone_id=arguments["milestone_id"])

            # Task tools
            elif name == "list_tasks":
                result = tools.list_tasks(
                    task_id=arguments.get("task_id"),
                    status=arguments.get("status"),
                    assignee=arguments.get("assignee"),
                    include_archived=arguments.get("include_archived", False),
                )
            elif name == "create_task":
                result = tools.create_task(
                    name=arguments["name"],
                    goal=arguments["goal"],
                    steps=arguments["steps"],
                    task_id=arguments.get("task_id"),
                    assignee=arguments.get("assignee"),
                )
            elif name == "update_task":
                result = tools.update_task(
                    task_id=arguments["task_id"],
                    status=arguments.get("status"),
                    name=arguments.get("name"),
                    goal=arguments.get("goal"),
                    assignee=arguments.get("assignee"),
                    step_id=arguments.get("step_id"),
                    step_status=arguments.get("step_status"),
                    steps=arguments.get("steps"),
                )
            elif name == "delete_task":
                result = tools.delete_task(task_id=arguments["task_id"])

            # Note tools
            elif name == "add_note":
                result = tools.add_note(
                    content=arguments["content"],
                    score=arguments.get("score", 15),
                )
            elif name == "update_note":
                result = tools.update_note(
                    note_id=arguments["note_id"],
                    content=arguments.get("content"),
                    score=arguments.get("score"),
                )
            elif name == "remove_note":
                result = tools.remove_note(note_id=arguments["note_id"])

            # Reference tools
            elif name == "add_reference":
                result = tools.add_reference(
                    url=arguments["url"],
                    note=arguments["note"],
                    score=arguments.get("score", 15),
                )
            elif name == "update_reference":
                result = tools.update_reference(
                    reference_id=arguments["reference_id"],
                    url=arguments.get("url"),
                    note=arguments.get("note"),
                    score=arguments.get("score"),
                )
            elif name == "remove_reference":
                result = tools.remove_reference(reference_id=arguments["reference_id"])

            else:
                raise ValueError(f"Unknown tool: {name}")

            return [TextContent(type="text", text=json.dumps(result, indent=2))]

        except Exception as e:
            return [TextContent(type="text", text=json.dumps({"error": str(e)}))]

    return server


async def main():
    """Run the MCP server."""
    server = create_server()
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream, server.create_initialization_options())


def run():
    """Entry point for the server."""
    import asyncio
    asyncio.run(main())


if __name__ == "__main__":
    run()
