"""
GitHub API Service - 統一 GitHub API 呼叫
=========================================
Phase 22 P0 修復: Router 層禁止直接 httpx.AsyncClient

遵循規範:
- Skill 09: Router 層禁止直接外部 API 呼叫
- feedback_lewooogo_modular_enforcement.md: Service 層封裝

功能:
- Fetch PR Diff (取得 PR 差異內容)
- 未來擴展: PR Comments, Status Checks, etc.

版本: v1.0
建立: 2026-03-31 (台北時區)
建立者: Claude Code (首席架構師 P0 修復)
"""

import httpx
import structlog

logger = structlog.get_logger(__name__)


# =============================================================================
# Constants
# =============================================================================

# 最大 diff 字元數 (約 12500 tokens)
MAX_DIFF_CHARS = 50000


# =============================================================================
# GitHub API Service
# =============================================================================


class GitHubApiService:
    """
    GitHub API Service

    統一 GitHub API 呼叫，符合 leWOOOgo 積木化原則

    2026-03-31 Claude Code (Phase 22 P0 修復)
    """

    def __init__(
        self,
        default_timeout: float = 30.0,
        max_diff_chars: int = MAX_DIFF_CHARS,
    ):
        self._default_timeout = default_timeout
        self._max_diff_chars = max_diff_chars

    async def fetch_pr_diff(
        self,
        diff_url: str,
        timeout: float | None = None,
    ) -> str:
        """
        取得 PR diff 內容

        Args:
            diff_url: GitHub diff URL
            timeout: 超時秒數 (預設 30s)

        Returns:
            str: diff 內容 (超過限制會截斷)
        """
        try:
            async with httpx.AsyncClient(
                timeout=timeout or self._default_timeout
            ) as client:
                response = await client.get(
                    diff_url,
                    headers={"Accept": "application/vnd.github.v3.diff"},
                )

                if response.status_code == 200:
                    diff_content = response.text

                    # 限制 diff 大小 (避免 LLM token 過多)
                    if len(diff_content) > self._max_diff_chars:
                        diff_content = (
                            diff_content[: self._max_diff_chars] + "\n... (truncated)"
                        )

                    return diff_content
                else:
                    logger.warning(
                        "github_diff_fetch_failed",
                        url=diff_url,
                        status=response.status_code,
                    )
                    return ""

        except httpx.TimeoutException:
            logger.warning("github_diff_fetch_timeout", url=diff_url)
            return ""
        except Exception as e:
            logger.warning("github_diff_fetch_error", error=str(e))
            return ""


# =============================================================================
# Singleton
# =============================================================================

_github_api_service: GitHubApiService | None = None


def get_github_api_service() -> GitHubApiService:
    """取得 GitHubApiService singleton"""
    global _github_api_service
    if _github_api_service is None:
        _github_api_service = GitHubApiService()
    return _github_api_service
