"""HTTP client utilities for gjalla-precommit API communication."""

from __future__ import annotations

import json
from typing import Any

import httpx


API_TIMEOUT = 30.0


def _make_headers(api_key: str) -> dict[str, str]:
    """Create headers for API requests."""
    return {
        "x-api-key": api_key,
        "Content-Type": "application/json",
        "Accept": "application/json",
    }


async def fetch_context_async(
    project_id: int | str, api_key: str, api_url: str
) -> dict[str, Any]:
    """Fetch project context from the API.

    Args:
        project_id: The project ID.
        api_key: The API key for authentication.
        api_url: The API base URL.

    Returns:
        Context dictionary from API.

    Raises:
        RuntimeError: If the API call fails.
    """
    try:
        async with httpx.AsyncClient() as client:
            response = await client.get(
                f"{api_url}/api/agent/projects/{project_id}/context/full",
                headers=_make_headers(api_key),
                timeout=API_TIMEOUT,
            )

            if response.status_code == 404:
                raise RuntimeError(f"Project {project_id} not found or access denied")

            if response.status_code != 200:
                raise RuntimeError(
                    f"API returned status {response.status_code}: {response.text}"
                )

            data = response.json()

            # Transform to cached context format
            return {
                "project_id": int(project_id),
                "schema_version": data.get("schema_version", "1.0.0"),
                "context_hash": data.get("context_hash"),
                "architecture": data.get("architecture", []),
                "capabilities": data.get("capabilities", []),
                "rules": data.get("rules", []),
                "fetched_at": data.get("fetched_at"),
            }

    except httpx.RequestError as e:
        raise RuntimeError(f"Network error fetching context: {e}") from e
    except json.JSONDecodeError as e:
        raise RuntimeError(f"Invalid JSON response: {e}") from e


def fetch_context(project_id: int | str, api_key: str, api_url: str) -> dict[str, Any]:
    """Fetch project context from the API (sync wrapper).

    Args:
        project_id: The project ID.
        api_key: The API key for authentication.
        api_url: The API base URL.

    Returns:
        Context dictionary from API.

    Raises:
        RuntimeError: If the API call fails.
    """
    import asyncio
    return asyncio.run(fetch_context_async(project_id, api_key, api_url))


def fetch_element_tree(
    project_id: int | str, api_key: str, api_url: str
) -> str | None:
    """Fetch the compact architecture tree from the agent API.

    Hits GET /api/agent/projects/{id}/context?type=architecture_spec&format=compact_markdown
    which returns a pre-rendered markdown tree with hierarchy, connections, files, and entities.

    Returns:
        Compact markdown string, or None if unavailable.
    """
    try:
        response = httpx.get(
            f"{api_url}/api/agent/projects/{project_id}/context",
            params={"type": "architecture_spec", "format": "compact_markdown"},
            headers=_make_headers(api_key),
            timeout=API_TIMEOUT,
        )
        if response.status_code != 200:
            return None
        data = response.json()
        content = data.get("content")
        if isinstance(content, str) and content.strip():
            return content
        return None
    except (httpx.RequestError, json.JSONDecodeError, KeyError):
        return None
