"""
Cliente HTTP para la API REST de Jama.

Centraliza las llamadas HTTP con autenticación JWT automática.
"""
from typing import Any

import httpx

from jama_agent.auth import load_credentials


class ApiError(Exception):
    """Error de la API con status code y detalle."""

    def __init__(self, status_code: int, detail: str):
        self.status_code = status_code
        self.detail = detail
        super().__init__(f"HTTP {status_code}: {detail}")


def _get_auth() -> tuple[str, str]:
    """Retorna (server, token) desde credenciales guardadas.

    Raises:
        ApiError: si no hay credenciales.
    """
    creds = load_credentials()
    if not creds or not creds.get("access_token"):
        raise ApiError(0, "No credentials. Run 'jama-agent login' first.")
    return creds["server"], creds["access_token"]


def _headers(token: str) -> dict[str, str]:
    return {"Authorization": f"Bearer {token}"}


def get(path: str, params: dict[str, Any] | None = None) -> dict[str, Any]:
    """GET request autenticado."""
    server, token = _get_auth()
    url = f"{server}{path}"
    resp = httpx.get(url, headers=_headers(token), params=params, timeout=30)
    if resp.status_code >= 400:
        detail = resp.text[:200]
        try:
            detail = resp.json().get("detail", detail)
        except Exception:
            pass
        raise ApiError(resp.status_code, detail)
    return resp.json()


def post(path: str, json_data: dict[str, Any] | None = None) -> dict[str, Any]:
    """POST request autenticado."""
    server, token = _get_auth()
    url = f"{server}{path}"
    resp = httpx.post(url, headers=_headers(token), json=json_data, timeout=30)
    if resp.status_code >= 400:
        detail = resp.text[:200]
        try:
            detail = resp.json().get("detail", detail)
        except Exception:
            pass
        raise ApiError(resp.status_code, detail)
    return resp.json()


def download(path: str, dest: str) -> str:
    """Descarga un archivo desde la API."""
    server, token = _get_auth()
    url = f"{server}{path}"
    with httpx.stream("GET", url, headers=_headers(token), timeout=60) as resp:
        if resp.status_code >= 400:
            raise ApiError(resp.status_code, f"Download failed: {resp.status_code}")
        with open(dest, "wb") as f:
            for chunk in resp.iter_bytes():
                f.write(chunk)
    return dest
