"""GitHub-related MCP tools (CI errors and PR comments)."""

from __future__ import annotations

from typing import TYPE_CHECKING, Annotated

from pydantic import Field

from aida_mcp.server.app_instance import Context
from aida_mcp.tools.github.ci_errors import CiErrorsOptions, get_ci_errors_for_pr
from aida_mcp.tools.github.comments import (
    GithubCommentsAction,
    list_review_threads,
    reply_to_review_comment,
    resolve_review_thread,
)
from aida_mcp.utils.workspace import get_workspace_root

if TYPE_CHECKING:
    from mcp.server.fastmcp import FastMCP


def register(mcp: FastMCP) -> None:
    """Register GitHub-related MCP tools."""
    mcp.tool()(github_ci_errors)
    mcp.tool()(github_comments)


async def github_ci_errors(
    pr_number: Annotated[int, Field(description="Pull request number (e.g., 19310)")],
    repo: Annotated[
        str,
        Field(
            description=(
                "Repository in 'owner/repo' format. "
                "If empty, defaults to the current repository implied by the workspace."
            )
        ),
    ] = "",
    max_failed_checks: Annotated[
        int,
        Field(description="Maximum number of failing check-runs to return (size cap). Default: 6"),
    ] = 6,
    max_annotations_per_check: Annotated[
        int,
        Field(description="Maximum number of failure annotations per check-run (size cap). Default: 30"),
    ] = 30,
    include_log_tails: Annotated[
        bool,
        Field(
            description=(
                "Best-effort include size-capped tail of Actions job log when check-run maps to a job. "
                "Default: False (annotations are preferred)."
            )
        ),
    ] = False,
    log_tail_max_bytes: Annotated[
        int,
        Field(description="Max bytes for job log tail when include_log_tails=True. Default: 65536"),
    ] = 65536,
    *,
    ctx: Context,
) -> object:
    """Fetch size-capped CI failures for a PR (errors-only by default)."""
    await ctx.info(f"🔎 Fetching CI errors for PR #{pr_number}…")

    workspace_root = await get_workspace_root(ctx)
    if not repo:
        # Best-effort: infer from git remote "origin" if possible.
        from aida_mcp.utils.git import get_repo_slug_from_git_remotes

        inferred = get_repo_slug_from_git_remotes(workspace_root)
        if not inferred:
            raise ValueError("repo is required when it cannot be inferred from git remotes.")
        repo = inferred

    opts = CiErrorsOptions(
        max_failed_checks=max_failed_checks,
        max_annotations_per_check=max_annotations_per_check,
        include_log_tails=include_log_tails,
        log_tail_max_bytes=log_tail_max_bytes,
    )
    return await get_ci_errors_for_pr(repo=repo, pr_number=pr_number, options=opts)


async def github_comments(
    action: Annotated[
        GithubCommentsAction,
        Field(
            description=(
                "Action to perform: "
                "'reply_to_review_comment' (threaded reply to inline review comment), "
                "'resolve_review_thread' (Resolve conversation for that thread), "
                "'list_review_threads' (list review threads for a PR)."
            )
        ),
    ],
    repo: Annotated[
        str,
        Field(description="Repository in 'owner/repo' format (required for list_review_threads)."),
    ] = "",
    pr_number: Annotated[
        int | None,
        Field(description="PR number (required for list_review_threads)."),
    ] = None,
    comment_url: Annotated[
        str,
        Field(
            description=(
                "GitHub URL to a PR review comment (must end with #discussion_r<ID>). "
                "Required for reply_to_review_comment and resolve_review_thread."
            )
        ),
    ] = "",
    body: Annotated[
        str,
        Field(description="Reply text (required for reply_to_review_comment)."),
    ] = "",
    limit: Annotated[
        int,
        Field(description="Max number of threads returned for list_review_threads (size cap). Default: 30"),
    ] = 30,
    include_resolved: Annotated[
        bool,
        Field(
            description=(
                "Include resolved threads in the output for list_review_threads (for context). "
                "Default: False (only unresolved threads)."
            )
        ),
    ] = False,
    *,
    ctx: Context,
) -> object:
    """GitHub PR review-thread operations (reply/resolve/list), non-interactive."""
    if action == "reply_to_review_comment":
        if not comment_url:
            raise ValueError("comment_url is required for reply_to_review_comment")
        if not body:
            raise ValueError("body is required for reply_to_review_comment")
        await ctx.info("💬 Replying in-thread to review comment…")
        return await reply_to_review_comment(comment_url=comment_url, body=body)

    if action == "resolve_review_thread":
        if not comment_url:
            raise ValueError("comment_url is required for resolve_review_thread")
        await ctx.info("✅ Resolving review thread…")
        return await resolve_review_thread(comment_url=comment_url)

    if action == "list_review_threads":
        if not repo:
            raise ValueError("repo is required for list_review_threads")
        if pr_number is None:
            raise ValueError("pr_number is required for list_review_threads")
        msg = "🧵 Listing review threads" + (" (including resolved)…" if include_resolved else "…")
        await ctx.info(msg)
        return await list_review_threads(repo=repo, pr_number=pr_number, limit=limit, include_resolved=include_resolved)

    raise ValueError(f"Unknown action: {action}")
