"""
HTTP client helpers for Nia Local Sync CLI.

Centralizes API base URL, auth headers, timeouts, and error handling.
"""
import httpx
from typing import Any

from config import get_api_key, get_api_base_url

DEFAULT_TIMEOUT = 30
CONNECT_TIMEOUT = 10


def _build_url(path: str) -> str:
    base_url = get_api_base_url().rstrip("/")
    return f"{base_url}{path}"


def _build_headers() -> dict[str, str]:
    api_key = get_api_key()
    if not api_key:
        return {}
    return {"Authorization": f"Bearer {api_key}"}


def request_json(
    method: str,
    path: str,
    *,
    payload: dict[str, Any] | None = None,
    params: dict[str, Any] | None = None,
    timeout: int = DEFAULT_TIMEOUT,
    requires_auth: bool = True,
) -> tuple[Any | None, str | None]:
    api_key = get_api_key()
    if requires_auth and not api_key:
        return None, "Not authenticated"

    url = _build_url(path)
    headers = _build_headers()

    try:
        with httpx.Client(timeout=httpx.Timeout(timeout, connect=CONNECT_TIMEOUT)) as client:
            response = client.request(
                method,
                url,
                headers=headers,
                json=payload,
                params=params,
            )
    except httpx.RequestError as e:
        return None, f"Network error: {e}"

    if 200 <= response.status_code < 300:
        try:
            return response.json(), None
        except ValueError:
            return response.text, None

    if response.status_code == 401:
        return None, "Authentication failed"

    try:
        detail = response.json().get("detail", response.text)
    except ValueError:
        detail = response.text or f"HTTP {response.status_code}"
    return None, f"API error: {detail}"


def get_sources() -> list[dict[str, Any]]:
    data, error = request_json("GET", "/v2/daemon/sources")
    if error or not isinstance(data, list):
        return []
    return data


def add_source(path: str, detected_type: str | None = None) -> dict[str, Any] | None:
    data, error = request_json(
        "POST",
        "/v2/daemon/sources",
        payload={"path": path, "detected_type": detected_type},
    )
    if error or not isinstance(data, dict):
        return None
    return data


def remove_source(local_folder_id: str) -> bool:
    data, error = request_json("DELETE", f"/v2/daemon/sources/{local_folder_id}")
    if error:
        return False
    return bool(data)


def enable_source_sync(local_folder_id: str, path: str) -> bool:
    data, error = request_json(
        "POST",
        f"/v2/daemon/sources/{local_folder_id}/enable",
        payload={"path": path},
    )
    if error:
        return False
    return bool(data)
