from __future__ import annotations

import asyncio
import logging
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager

from mcp.server.fastmcp import FastMCP
from mrp import Agent

from mrp_mcp.config import Config
from mrp_mcp.state import SessionState
from mrp_mcp.tools import agent as agent_tools
from mrp_mcp.tools import blobs, discovery, messaging, threads

logger = logging.getLogger("mrp_mcp")


async def background_poller(
    mrp_agent: Agent,
    state: SessionState,
    interval: float,
) -> None:
    """Poll for messages in the background."""
    while True:
        await asyncio.sleep(interval)
        try:
            result = await asyncio.to_thread(
                mrp_agent.client.poll_messages,
                status="sent",
                limit=50,
                cursor=state.last_poll_cursor,
            )
            if result.messages:
                state.unread.extend(result.messages)
            if result.next_cursor:
                state.last_poll_cursor = result.next_cursor
        except Exception:
            pass


def create_server(config: Config) -> FastMCP:
    """Create and configure the MCP server with all tools registered."""
    mrp_agent = Agent(
        relay=config.relay_url,
        key_file=config.key_file,
        name=config.agent_name,
        capabilities=config.capabilities or None,
        metadata=config.metadata or None,
    )

    if config.auto_register:
        mrp_agent.register()

    state = SessionState()

    # Set up lifespan for background poller
    @asynccontextmanager
    async def lifespan(server: FastMCP) -> AsyncIterator[None]:
        poller_task = None
        if config.poll_interval > 0:
            poller_task = asyncio.create_task(
                background_poller(mrp_agent, state, config.poll_interval)
            )
        try:
            yield
        finally:
            if poller_task:
                poller_task.cancel()

    mcp = FastMCP("mrp-mcp", lifespan=lifespan)

    discovery.register(mcp, mrp_agent, state)
    messaging.register(mcp, mrp_agent, state)
    threads.register(mcp, mrp_agent, state)
    blobs.register(mcp, mrp_agent, state)
    agent_tools.register(mcp, mrp_agent, state)

    return mcp


def run_server(config: Config) -> None:
    """Create and run the MCP server (blocking)."""
    mcp = create_server(config)
    mcp.run()
