import aiohttp

from ..logger import logger
from ..models import Issue, Repository


async def fetch_forgejo_issue(repository: Repository, issue_number: int) -> Issue:
    """
    Fetch an issue from a Forgejo instance.
    Args:
        repository (Repository): The repository to fetch the issue from.
        issue_number (int): The issue number.
    Returns:
        Issue: An Issue object containing the issue details.
    Raises:
        aiohttp.ClientResponseError: If the request to the Forgejo API fails.
        ValueError: If the response from the Forgejo API is empty
    """
    headers: dict[str, str] = {"User-Agent": repository.user_agent}
    if repository.provider.token is not None:
        headers["Authorization"] = f"token {repository.provider.token}"
    else:
        logger.info("Forgejo API key is not set for provider '%s'. Using unauthenticated request.", repository.provider.url)
    url = f"{repository.provider.api_url}/repos/{repository.owner}/{repository.name}/issues/{issue_number}"
    async with aiohttp.ClientSession() as session:
        async with session.get(url, headers=headers) as response:
            if response.status != 200:
                raise aiohttp.ClientResponseError(
                    request_info=response.request_info,
                    history=response.history,
                    status=response.status,
                    message=f"Failed to fetch issue '{issue_number}' from '{repository.url}'.",
                )
            data = await response.json()

    if data is None:
        raise ValueError("Received empty response from Forgejo API.")

    pull_request = data.get("pull_request")
    if pull_request is not None:
        if pull_request["merged"] is True:
            issue_type = "pull_request_merged"
        elif pull_request["draft"] is True:
            issue_type = "pull_request_draft"
        elif data.get("state", "open") == "closed":
            issue_type = "pull_request_closed"
        else:
            issue_type = "pull_request"
    elif data.get("state", "open") == "closed":
        issue_type = "issue_closed"
    else:
        issue_type = "issue"

    return Issue(
        repository=repository,
        number=data["number"],
        author=data["user"]["login"],
        author_avatar=data["user"]["avatar_url"],
        author_url=data["user"]["html_url"],
        link=data["html_url"],
        title=data["title"],
        body=data["body"] or "",
        type=issue_type,
        labels=[label["name"] for label in data.get("labels", [])],
        draft=bool(data["pull_request"].get("draft", False) if data.get("pull_request") is not None else False),
        creation_date=data["created_at"],
        milestone=data.get("milestone", {}).get("title") if data.get("milestone") is not None else None,
        merge_date=data.get("pull_request").get("merged_at") if data.get("pull_request") is not None else None,
        response=response,
    )