"""GitHub API tools."""

from pydantic_ai import RunContext
from pydantic_ai.toolsets import FunctionToolset

from pydanticai_multiagent.dependencies import BaseDeps

github_toolset: FunctionToolset[BaseDeps] = FunctionToolset()


@github_toolset.tool
async def search_issues(
    ctx: RunContext[BaseDeps],
    repo: str,
    query: str,
    state: str = "open",
    limit: int = 10,
) -> str:
    """Search for issues in a GitHub repository.

    Args:
        ctx: The run context with dependencies.
        repo: Repository in format 'owner/repo'.
        query: Search query for issue titles/bodies.
        state: Issue state - 'open', 'closed', or 'all'.
        limit: Maximum number of issues to return.
    """
    response = await ctx.deps.http_client.get(
        "https://api.github.com/search/issues",
        params={
            "q": f"{query} repo:{repo} state:{state} is:issue",
            "per_page": limit,
        },
    )
    data = response.json()
    issues = data.get("items", [])

    if not issues:
        return f"No issues found matching '{query}' in {repo}"

    formatted = []
    for issue in issues:
        formatted.append(
            f"#{issue['number']}: {issue['title']}\n"
            f"  State: {issue['state']} | Labels: {', '.join(l['name'] for l in issue['labels'])}\n"
            f"  URL: {issue['html_url']}"
        )

    return "\n\n".join(formatted)


@github_toolset.tool
async def get_issue_details(
    ctx: RunContext[BaseDeps],
    repo: str,
    issue_number: int,
) -> str:
    """Get detailed information about a specific issue.

    Args:
        ctx: The run context with dependencies.
        repo: Repository in format 'owner/repo'.
        issue_number: The issue number.
    """
    response = await ctx.deps.http_client.get(
        f"https://api.github.com/repos/{repo}/issues/{issue_number}",
    )
    issue = response.json()

    return f"""Issue #{issue['number']}: {issue['title']}
State: {issue['state']}
Author: {issue['user']['login']}
Created: {issue['created_at']}
Labels: {', '.join(l['name'] for l in issue['labels'])}

{issue['body'] or 'No description provided.'}"""


@github_toolset.tool
async def list_pull_requests(
    ctx: RunContext[BaseDeps],
    repo: str,
    state: str = "open",
    limit: int = 10,
) -> str:
    """List pull requests in a repository.

    Args:
        ctx: The run context with dependencies.
        repo: Repository in format 'owner/repo'.
        state: PR state - 'open', 'closed', or 'all'.
        limit: Maximum number of PRs to return.
    """
    response = await ctx.deps.http_client.get(
        f"https://api.github.com/repos/{repo}/pulls",
        params={"state": state, "per_page": limit},
    )
    prs = response.json()

    if not prs:
        return f"No pull requests found in {repo} with state '{state}'"

    formatted = []
    for pr in prs:
        formatted.append(
            f"#{pr['number']}: {pr['title']}\n"
            f"  Author: {pr['user']['login']} | State: {pr['state']}\n"
            f"  {pr['head']['ref']} -> {pr['base']['ref']}"
        )

    return "\n\n".join(formatted)


@github_toolset.tool
async def get_repository_info(
    ctx: RunContext[BaseDeps],
    repo: str,
) -> str:
    """Get information about a repository.

    Args:
        ctx: The run context with dependencies.
        repo: Repository in format 'owner/repo'.
    """
    response = await ctx.deps.http_client.get(
        f"https://api.github.com/repos/{repo}",
    )
    data = response.json()

    return f"""Repository: {data['full_name']}
Description: {data['description'] or 'No description'}
Stars: {data['stargazers_count']} | Forks: {data['forks_count']}
Language: {data['language']}
Default Branch: {data['default_branch']}
Open Issues: {data['open_issues_count']}
URL: {data['html_url']}"""
