"""
Phase 79: Swarm State Machine MCP Microservice Tools.

Exposes the Phase 69 Swarm State Machine as MCP tools.
"""

from mcp.types import TextContent, Tool, ToolAnnotations

_SAFE_READ = ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False)
_SAFE_WRITE = ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False, openWorldHint=False)

TOOLS = [
    Tool(
        name="swarm_create",
        description="Create a new swarm session. Starts in PLANNING state.",
        inputSchema={
            "type": "object",
            "properties": {
                "name": {"type": "string", "description": "Swarm name"},
                "task_description": {"type": "string", "description": "What the swarm should accomplish"},
                "required_skills": {"type": "array", "items": {"type": "string"}},
                "max_agents": {"type": "integer", "description": "Max agents (default: 5)"},
            },
            "required": ["name", "task_description"],
        },
        annotations=_SAFE_WRITE,
    ),
    Tool(
        name="swarm_transition",
        description="Move a swarm to a new state. Validates allowed transitions.",
        inputSchema={
            "type": "object",
            "properties": {
                "session_id": {"type": "string"},
                "new_state": {
                    "type": "string",
                    "enum": ["PLANNING", "RECRUITING", "EXECUTING", "REVIEWING", "COMPLETED", "FAILED", "BLOCKED"],
                },
                "reason": {"type": "string"},
            },
            "required": ["session_id", "new_state"],
        },
        annotations=_SAFE_WRITE,
    ),
    Tool(
        name="swarm_assign_agent",
        description="Add an agent to a swarm with a role (lead/worker/reviewer).",
        inputSchema={
            "type": "object",
            "properties": {
                "session_id": {"type": "string"},
                "agent_id": {"type": "string"},
                "role": {"type": "string", "enum": ["lead", "worker", "reviewer"]},
            },
            "required": ["session_id", "agent_id"],
        },
        annotations=_SAFE_WRITE,
    ),
    Tool(
        name="swarm_report_progress",
        description="Agent reports progress on their swarm work.",
        inputSchema={
            "type": "object",
            "properties": {
                "session_id": {"type": "string"},
                "agent_id": {"type": "string"},
                "progress_pct": {"type": "number", "description": "0-100"},
                "status_message": {"type": "string"},
            },
            "required": ["session_id", "agent_id", "progress_pct"],
        },
        annotations=_SAFE_WRITE,
    ),
    Tool(
        name="swarm_check_blocked",
        description="Check if a swarm has stuck agents.",
        inputSchema={
            "type": "object",
            "properties": {
                "session_id": {"type": "string"},
            },
            "required": ["session_id"],
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="swarm_list",
        description="List swarm sessions, optionally filtered by state.",
        inputSchema={
            "type": "object",
            "properties": {
                "state": {"type": "string", "description": "Filter by state"},
                "limit": {"type": "integer"},
            },
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="swarm_stats",
        description="Get swarm statistics.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_READ,
    ),
]


# ── Handlers ───────────────────────────────────────────────────────────────

import json


async def _handle_create(args: dict) -> list[TextContent]:
    from brynq.swarm_state_machine import create_swarm_session
    try:
        sid = create_swarm_session(
            name=args["name"],
            task_description=args["task_description"],
            required_skills=args.get("required_skills"),
            max_agents=args.get("max_agents", 5),
        )
        return [TextContent(type="text", text=f"Swarm session created: {sid}")]
    except ValueError as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def _handle_transition(args: dict) -> list[TextContent]:
    from brynq.swarm_state_machine import transition
    try:
        session = transition(
            session_id=args["session_id"],
            new_state=args["new_state"],
            reason=args.get("reason", ""),
        )
        return [TextContent(type="text", text=f"Transitioned to {session['state']}")]
    except (FileNotFoundError, ValueError) as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def _handle_assign(args: dict) -> list[TextContent]:
    from brynq.swarm_state_machine import assign_agent
    try:
        session = assign_agent(
            session_id=args["session_id"],
            agent_id=args["agent_id"],
            role=args.get("role", "worker"),
        )
        count = len(session.get("agents", {}))
        return [TextContent(type="text", text=f"Agent assigned. Total agents: {count}")]
    except (FileNotFoundError, ValueError) as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def _handle_progress(args: dict) -> list[TextContent]:
    from brynq.swarm_state_machine import report_progress
    try:
        report_progress(
            session_id=args["session_id"],
            agent_id=args["agent_id"],
            progress_pct=args["progress_pct"],
            status_message=args.get("status_message", ""),
        )
        return [TextContent(type="text", text=f"Progress reported: {args['progress_pct']}%")]
    except (FileNotFoundError, ValueError) as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def _handle_check_blocked(args: dict) -> list[TextContent]:
    from brynq.swarm_state_machine import check_blocked
    try:
        result = check_blocked(args["session_id"])
        return [TextContent(type="text", text=json.dumps(result, indent=2))]
    except FileNotFoundError as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def _handle_list(args: dict) -> list[TextContent]:
    from brynq.swarm_state_machine import list_sessions
    sessions = list_sessions(
        state=args.get("state"),
        limit=args.get("limit", 20),
    )
    return [TextContent(type="text", text=json.dumps(sessions, indent=2, default=str))]


async def _handle_stats(args: dict) -> list[TextContent]:
    from brynq.swarm_state_machine import get_swarm_stats
    stats = get_swarm_stats()
    return [TextContent(type="text", text=json.dumps(stats, indent=2, default=str))]


HANDLERS = {
    "swarm_create": _handle_create,
    "swarm_transition": _handle_transition,
    "swarm_assign_agent": _handle_assign,
    "swarm_report_progress": _handle_progress,
    "swarm_check_blocked": _handle_check_blocked,
    "swarm_list": _handle_list,
    "swarm_stats": _handle_stats,
}
