"""Reddit search tools."""

from mcp.server.fastmcp import FastMCP
from praw.models import Comment
from prawcore.exceptions import PrawcoreException

from reddit_mcp.reddit_client import get_reddit
from reddit_mcp.serializers import serialize_redditor, serialize_submission


def search_all(
    query: str, sort: str = "relevance", time_filter: str = "all", limit: int = 25
) -> list[dict]:
    """Search all of Reddit for posts matching query.

    Use this to find posts across all subreddits. Supports sorting by relevance,
    popularity, recency, and comment count. Time filters help narrow results to
    recent content.

    Args:
        query: Search terms (supports Reddit search syntax like
            'author:', 'flair:', etc.)
        sort: Sort order - 'relevance' (default), 'hot', 'top', 'new', 'comments'
        time_filter: Time period - 'all' (default), 'day', 'hour',
            'month', 'week', 'year'
        limit: Maximum results to return (1-100, default 25)

    Returns:
        List of post dictionaries with title, author, score, url, subreddit, etc.

    Examples:
        - search_all("python tutorial", sort="top", time_filter="month")
        - search_all("author:spez", limit=10)
        - search_all("flair:Discussion", sort="new")
    """
    reddit = get_reddit()
    results = reddit.subreddit("all").search(
        query, sort=sort, time_filter=time_filter, limit=min(limit, 100)
    )
    return [serialize_submission(s) for s in results]


def search_subreddit(
    subreddit: str,
    query: str,
    sort: str = "relevance",
    time_filter: str = "all",
    limit: int = 25,
) -> list[dict]:
    """Search within a specific subreddit for posts matching query.

    More focused than search_all - only returns results from the
    specified subreddit.
    Useful when you know which community to search in.

    Args:
        subreddit: Subreddit name (without r/ prefix, e.g., 'python' not 'r/python')
        query: Search terms (supports Reddit search syntax)
        sort: Sort order - 'relevance' (default), 'hot', 'top', 'new', 'comments'
        time_filter: Time period - 'all' (default), 'day', 'hour',
            'month', 'week', 'year'
        limit: Maximum results to return (1-100, default 25)

    Returns:
        List of post dictionaries from the specified subreddit.

    Examples:
        - search_subreddit("python", "pandas dataframe", sort="top")
        - search_subreddit("AskReddit", "what is your",
            time_filter="week", limit=50)
        - search_subreddit("programming", "flair:Career", sort="new")
    """
    reddit = get_reddit()
    sub = reddit.subreddit(subreddit)
    results = sub.search(
        query, sort=sort, time_filter=time_filter, limit=min(limit, 100)
    )
    return [serialize_submission(s) for s in results]


def search_comments(
    query: str, subreddit: str | None = None, limit: int = 25
) -> list[dict]:
    """Search for comments matching query.

    NOTE: Reddit's native comment search is limited. This searches for posts
    containing the query and returns their top comments as a workaround.
    For comprehensive comment search, external services like Pushshift would
    be needed (currently unavailable via official API).

    Args:
        query: Search terms to find in comments
        subreddit: Optional subreddit name to limit search (without r/ prefix)
        limit: Maximum number of posts to search through (1-100, default 25)

    Returns:
        List of comment dictionaries from posts matching the query.
        Note: This is a best-effort implementation with limitations.

    Examples:
        - search_comments("thank you for the gold", limit=10)
        - search_comments("this is the way", subreddit="PrequelMemes")
    """
    reddit = get_reddit()

    if subreddit:
        search_results = reddit.subreddit(subreddit).search(
            query, limit=min(limit, 100)
        )
    else:
        search_results = reddit.subreddit("all").search(query, limit=min(limit, 100))

    comments = []
    for submission in search_results:
        submission.comments.replace_more(limit=0)
        for comment in submission.comments.list()[:5]:
            if not isinstance(comment, Comment):
                continue
            if query.lower() in comment.body.lower():
                comments.append(
                    {
                        "id": comment.id,
                        "author": str(comment.author)
                        if comment.author
                        else "[deleted]",
                        "body": comment.body,
                        "score": comment.score,
                        "created_utc": comment.created_utc,
                        "permalink": f"https://reddit.com{comment.permalink}",
                        "post_title": submission.title,
                        "subreddit": str(submission.subreddit),
                    }
                )
                if len(comments) >= limit:
                    return comments

    return comments


def search_users(query: str, limit: int = 25) -> list[dict]:
    """Search for Reddit users (Redditors) by username.

    Finds user accounts matching the search query. Useful for discovering
    users or verifying username availability.

    Args:
        query: Username search term (partial matches supported)
        limit: Maximum results to return (1-100, default 25)

    Returns:
        List of user dictionaries with username, karma, account age, etc.

    Examples:
        - search_users("spez")
        - search_users("AutoModerator")
        - search_users("bot", limit=50)
    """
    reddit = get_reddit()

    results = reddit.subreddit("all").search(f"author:{query}", limit=min(limit, 100))

    seen_users: set[str] = set()
    users = []

    for submission in results:
        if submission.author and str(submission.author) not in seen_users:
            seen_users.add(str(submission.author))
            try:
                redditor = reddit.redditor(str(submission.author))
                users.append(serialize_redditor(redditor))
                if len(users) >= limit:
                    break
            except PrawcoreException:
                continue

    return users


def register_search_tools(mcp: FastMCP) -> None:
    """Register all search tools."""
    mcp.tool()(search_all)
    mcp.tool()(search_subreddit)
    mcp.tool()(search_comments)
    mcp.tool()(search_users)
