"""HTTP client for the SHIP Protocol API."""

from __future__ import annotations

from typing import Optional

import httpx

from .models import (
    CrawlerStatus,
    DetectResult,
    HealthStatus,
    ScoreResult,
    ToolInfo,
    ToolsResult,
)

DEFAULT_BASE_URL = "https://ship-protocol.dhruvaapi.workers.dev"
DEFAULT_TIMEOUT = 30.0


class ShipClient:
    """Client for the SHIP Protocol API.

    Usage::

        client = ShipClient()
        result = client.score(
            repo="owner/repo",
            message="feat: add auth",
            language="python",
        )
        print(result.score, result.grade)
    """

    def __init__(
        self,
        base_url: str = DEFAULT_BASE_URL,
        timeout: float = DEFAULT_TIMEOUT,
        api_key: Optional[str] = None,
    ) -> None:
        self.base_url = base_url.rstrip("/")
        headers: dict[str, str] = {
            "Content-Type": "application/json",
        }
        if api_key:
            headers["Authorization"] = f"Bearer {api_key}"
        self._client = httpx.Client(
            timeout=timeout, headers=headers,
        )

    def score(
        self,
        repo: str,
        message: str,
        language: str = "python",
        tool: str = "claude",
    ) -> ScoreResult:
        """Score an AI-generated commit for reliability."""
        owner = repo.split("/")[0] if "/" in repo else repo
        payload = {
            "repo": repo,
            "owner": owner,
            "commit_message": message,
            "language": language,
            "tool": tool,
        }
        resp = self._client.post(
            f"{self.base_url}/v2/score", json=payload,
        )
        resp.raise_for_status()
        return ScoreResult.model_validate(resp.json())

    def detect(
        self,
        code: str,
        language: str = "python",
    ) -> DetectResult:
        """Detect whether code is AI-generated."""
        payload = {"code": code, "language": language}
        resp = self._client.post(
            f"{self.base_url}/v2/detect", json=payload,
        )
        resp.raise_for_status()
        return DetectResult.model_validate(resp.json())

    def tools(self) -> list[ToolInfo]:
        """Get AI tool reliability rankings."""
        resp = self._client.get(f"{self.base_url}/v2/tools")
        resp.raise_for_status()
        result = ToolsResult.model_validate(resp.json())
        return result.tools

    def crawler_status(self) -> CrawlerStatus:
        """Get crawler/data stats."""
        resp = self._client.get(
            f"{self.base_url}/v2/crawler-status",
        )
        resp.raise_for_status()
        return CrawlerStatus.model_validate(resp.json())

    def health(self) -> HealthStatus:
        """Check API health and return aggregated status."""
        try:
            status = self.crawler_status()
            return HealthStatus(
                api_reachable=True,
                api_url=self.base_url,
                total_commits=status.total_commits,
                total_repos=status.total_repos,
            )
        except Exception as exc:
            return HealthStatus(
                api_reachable=False,
                api_url=self.base_url,
                error=str(exc),
            )

    def close(self) -> None:
        """Close the underlying HTTP client."""
        self._client.close()

    def __enter__(self) -> "ShipClient":
        return self

    def __exit__(self, *args: object) -> None:
        self.close()
