"""Gitea REST client — thin wrapper for PR creation and issue commenting.

Uses ``settings.gitea_url``, ``settings.gitea_token``, and
``settings.gitea_repo`` (owner/repo) from config.  Degrades gracefully
when the token is absent or the server is unreachable.
"""

from __future__ import annotations

import logging
from dataclasses import dataclass

logger = logging.getLogger(__name__)


@dataclass
class PullRequest:
    """Minimal representation of a created pull request."""

    number: int
    title: str
    html_url: str


class GiteaClient:
    """HTTP client for Gitea's REST API v1.

    All methods return structured results and never raise — errors are
    logged at WARNING level and indicated via return value.
    """

    def __init__(
        self,
        base_url: str | None = None,
        token: str | None = None,
        repo: str | None = None,
    ) -> None:
        from config import settings

        self._base_url = (base_url or settings.gitea_url).rstrip("/")
        self._token = token or settings.gitea_token
        self._repo = repo or settings.gitea_repo

    # ── internal ────────────────────────────────────────────────────────────

    def _headers(self) -> dict[str, str]:
        return {
            "Authorization": f"token {self._token}",
            "Content-Type": "application/json",
        }

    def _api(self, path: str) -> str:
        return f"{self._base_url}/api/v1/{path.lstrip('/')}"

    # ── public API ───────────────────────────────────────────────────────────

    def create_pull_request(
        self,
        title: str,
        body: str,
        head: str,
        base: str = "main",
    ) -> PullRequest | None:
        """Open a pull request.

        Args:
            title: PR title (keep under 70 chars).
            body:  PR body in markdown.
            head:  Source branch (e.g. ``self-modify/issue-983``).
            base:  Target branch (default ``main``).

        Returns:
            A ``PullRequest`` dataclass on success, ``None`` on failure.
        """
        if not self._token:
            logger.warning("Gitea token not configured — skipping PR creation")
            return None

        try:
            import requests as _requests

            resp = _requests.post(
                self._api(f"repos/{self._repo}/pulls"),
                headers=self._headers(),
                json={"title": title, "body": body, "head": head, "base": base},
                timeout=15,
            )
            resp.raise_for_status()
            data = resp.json()
            pr = PullRequest(
                number=data["number"],
                title=data["title"],
                html_url=data["html_url"],
            )
            logger.info("PR #%d created: %s", pr.number, pr.html_url)
            return pr
        except Exception as exc:
            logger.warning("Failed to create PR: %s", exc)
            return None

    def add_issue_comment(self, issue_number: int, body: str) -> bool:
        """Post a comment on an issue or PR.

        Returns:
            True on success, False on failure.
        """
        if not self._token:
            logger.warning("Gitea token not configured — skipping issue comment")
            return False

        try:
            import requests as _requests

            resp = _requests.post(
                self._api(f"repos/{self._repo}/issues/{issue_number}/comments"),
                headers=self._headers(),
                json={"body": body},
                timeout=15,
            )
            resp.raise_for_status()
            logger.info("Comment posted on issue #%d", issue_number)
            return True
        except Exception as exc:
            logger.warning("Failed to post comment on issue #%d: %s", issue_number, exc)
            return False


# Module-level singleton
gitea_client = GiteaClient()
