"""
MCP tool definitions.

Each function is decorated with @mcp.tool and becomes a callable tool
for any AI agent connected via the Model Context Protocol.
"""

from datetime import datetime, timezone, timedelta

from fastmcp import FastMCP

from polymarket_mcp.client import (
    get_market_by_id,
    get_markets,
    get_orderbook,
    get_price_history,
    search_markets_api,
)
from polymarket_mcp.analysis import (
    filter_closing_soon,
    format_market,
    format_market_summary,
    format_orderbook,
    format_price_history,
    rank_by_newest,
    rank_by_volume,
)


def register_tools(mcp: FastMCP) -> None:
    """Attach all Polymarket tools to the given FastMCP server."""

    # ── Market Discovery ─────────────────────────────────────────

    @mcp.tool
    async def search_markets(query: str, limit: int = 20) -> list[dict]:
        """Search Polymarket markets by keyword.

        Full-text search across all markets — the same search that
        powers the Polymarket website. Works for any topic:
        "Bitcoin", "NBA", "Trump", "OpenAI", "World Cup", etc.
        """
        raw = await search_markets_api(query, limit=limit)
        return [format_market(m) for m in raw]

    @mcp.tool
    async def trending_markets(limit: int = 10) -> list[dict]:
        """Get the hottest markets right now, ranked by 24-hour volume.

        Great for a quick overview of what the prediction-market
        crowd is trading today.
        """
        raw = await get_markets(limit=100, order="volume24hr", ascending=False)
        ranked = rank_by_volume(raw, limit=limit)
        return [format_market(m) for m in ranked]

    @mcp.tool
    async def new_markets(limit: int = 10) -> list[dict]:
        """Return the newest markets on Polymarket.

        Useful for discovering freshly launched prediction markets
        before they gain traction.
        """
        raw = await get_markets(limit=100, order="createdAt", ascending=False)
        ranked = rank_by_newest(raw, limit=limit)
        return [format_market(m) for m in ranked]

    @mcp.tool
    async def markets_closing_soon(hours: int = 24) -> list[dict]:
        """Find markets that resolve within the next *hours* hours.

        Uses end_date_min/max filters to only fetch markets ending
        in the requested time window. Handy for spotting imminent
        outcomes.
        """
        now = datetime.now(timezone.utc)
        end_max = now + timedelta(hours=hours)
        raw = await get_markets(
            limit=100,
            order="endDate",
            ascending=True,
            end_date_min=now.strftime("%Y-%m-%dT%H:%M:%SZ"),
            end_date_max=end_max.strftime("%Y-%m-%dT%H:%M:%SZ"),
        )
        closing = filter_closing_soon(raw, hours=hours)
        return [format_market(m) for m in closing]

    # ── Market Analysis ──────────────────────────────────────────

    @mcp.tool
    async def market_summary(market_id: str) -> dict:
        """Get a detailed summary of a single market.

        Returns probability, volume, liquidity, spread, best bid/ask,
        last trade price, description, outcomes, and more.
        Pass either a numeric market ID or a slug.
        """
        raw = await get_market_by_id(market_id)
        return format_market_summary(raw)

    @mcp.tool
    async def market_orderbook(token_id: str) -> dict:
        """Fetch the live orderbook for a market token.

        Shows current bids, asks, spread, depth, and last trade price.
        You need a token_id (found in search/summary results under
        'token_ids') to call this.
        """
        raw = await get_orderbook(token_id)
        return format_orderbook(raw)

    @mcp.tool
    async def market_price_history(
        token_id: str,
        interval: str = "1w",
        fidelity: int = 60,
    ) -> dict:
        """Get historical price data for a market token.

        Returns a time series of prices plus summary stats (min, max,
        price change, % change).

        Args:
            token_id: Token ID from market data (see 'token_ids' field).
            interval: Time window — "1h", "6h", "1d", "1w", "1m", "all".
            fidelity: Data granularity in minutes (default 60 = hourly).
        """
        raw = await get_price_history(token_id, interval=interval, fidelity=fidelity)
        return format_price_history(raw)
