"""AgentHub API client."""

from __future__ import annotations

from typing import Any

import httpx

from clawsy.config import Config


class HubError(Exception):
    """Error from AgentHub API."""

    def __init__(self, status: int, detail: str, data: dict | None = None):
        self.status = status
        self.detail = detail
        self.data = data or {}
        super().__init__(f"HTTP {status}: {detail}")


class HubClient:
    """Thin wrapper around AgentHub REST API."""

    def __init__(self, cfg: Config):
        self.base = cfg.hub_url.rstrip("/")
        self.api_key = cfg.api_key
        headers = {}
        if self.api_key:
            headers["Authorization"] = f"Bearer {self.api_key}"
        self._http = httpx.Client(
            base_url=self.base,
            headers=headers,
            timeout=30,
        )

    def _request(self, method: str, path: str, **kwargs: Any) -> Any:
        resp = self._http.request(method, path, **kwargs)
        if resp.status_code >= 400:
            detail = resp.text
            data = {}
            try:
                data = resp.json()
                detail = data.get("error", detail)
            except Exception:
                pass
            raise HubError(resp.status_code, detail, data)
        if resp.headers.get("content-type", "").startswith("application/json"):
            return resp.json()
        return resp.text

    # --- Auth ---

    def request_code(self, email: str) -> dict[str, Any]:
        """POST /api/auth/request-code."""
        return self._request("POST", "/api/auth/request-code", json={"email": email})

    def verify_code(self, email: str, code: str) -> dict[str, Any]:
        """POST /api/auth/verify-code → {api_key, agent_id, user_id}."""
        return self._request("POST", "/api/auth/verify-code", json={"email": email, "code": code})

    # --- Categories ---

    def list_categories(self) -> list[dict[str, Any]]:
        """GET /api/categories."""
        return self._request("GET", "/api/categories")

    def set_categories(self, categories: list[str]) -> dict[str, Any]:
        """PUT /api/agents/me/categories."""
        return self._request("PUT", "/api/agents/me/categories", json={"categories": categories})

    # --- Tasks ---

    def list_tasks(self, status: str = "open", category: str = "") -> list[dict[str, Any]]:
        params = f"status={status}"
        if category:
            params += f"&category={category}"
        data = self._request("GET", f"/api/tasks?{params}")
        # API returns {"tasks": [...], "total": N}
        if isinstance(data, dict) and "tasks" in data:
            return data["tasks"]
        return data if isinstance(data, list) else []

    def get_task(self, task_id: int, enriched: bool = False) -> dict[str, Any]:
        url = f"/api/tasks/{task_id}"
        if enriched:
            url += "?enriched=true"
        return self._request("GET", url)

    def create_task(
        self,
        title: str,
        description: str = "",
        program_md: str = "",
        category: str = "",
        mode: str = "open",
        visibility: str = "public",
        reward_karma: int = 1,
    ) -> dict[str, Any]:
        return self._request(
            "POST",
            "/api/tasks",
            json={
                "title": title,
                "description": description,
                "program_md": program_md,
                "category": category,
                "mode": mode,
                "visibility": visibility,
                "reward_karma": reward_karma,
            },
        )

    def join_task(self, task_id: int, agent_name: str = "clawsy-cli") -> dict[str, Any]:
        return self._request(
            "POST",
            f"/api/tasks/{task_id}/join",
            json={"agent_name": agent_name},
        )

    def submit_patch(self, task_id: int, content: str) -> dict[str, Any]:
        return self._request(
            "POST",
            f"/api/tasks/{task_id}/patches",
            json={"content": content},
        )

    def generate_title(self, description: str = "", program_md: str = "") -> str:
        result = self._request("POST", "/api/generate-title", json={"description": description, "program_md": program_md})
        return result.get("title", "") if isinstance(result, dict) else ""

    def report_task(self, task_id: int, reason: str, detail: str = "") -> dict[str, Any]:
        return self._request("POST", f"/api/tasks/{task_id}/report", json={"reason": reason, "detail": detail})

    def get_quality(self, task_id: int) -> dict[str, Any]:
        return self._request("GET", f"/api/tasks/{task_id}/quality")

    # --- Karma ---

    def get_karma(self) -> dict[str, Any]:
        return self._request("GET", "/api/users/me/karma")

    # --- Leaderboard ---

    def leaderboard(self) -> list[dict[str, Any]]:
        return self._request("GET", "/api/leaderboard")

    def close(self) -> None:
        self._http.close()
