"""Async HTTP client for the Abbe Core API."""

from __future__ import annotations

import os
from typing import Any

import httpx

TIMEOUT = 30.0


def _get_config() -> tuple[str, str]:
    """Read API URL and key from environment. Raises if key is missing."""
    url = os.environ.get("ABBE_API_URL", "https://abbeapi.com")
    key = os.environ.get("ABBE_API_KEY")
    if not key:
        raise RuntimeError(
            "ABBE_API_KEY environment variable is not set. "
            "Get an API key from BGI and add it to your MCP config."
        )
    return url.rstrip("/"), key


async def _request(
    method: str,
    path: str,
    *,
    json: dict[str, Any] | None = None,
    params: dict[str, Any] | None = None,
) -> dict[str, Any]:
    """Make an authenticated request to the Abbe API.

    Raises RuntimeError with the API error message on non-2xx responses.
    """
    base_url, api_key = _get_config()
    headers = {"X-API-Key": api_key}

    async with httpx.AsyncClient(timeout=TIMEOUT) as client:
        resp = await client.request(
            method,
            f"{base_url}{path}",
            headers=headers,
            json=json,
            params=params,
        )

    if resp.status_code >= 400:
        try:
            body = resp.json()
            err = body.get("error", {})
            msg = err.get("message", resp.text)
        except Exception:
            msg = resp.text
        raise RuntimeError(f"Abbe API error ({resp.status_code}): {msg}")

    return resp.json()


async def resolve(
    queries: list[dict[str, Any]],
    top_k: int = 5,
    min_confidence: float = 0.0,
) -> dict[str, Any]:
    """POST /v1/resolve — resolve job titles to SOC occupations."""
    return await _request(
        "POST",
        "/v1/resolve",
        json={
            "queries": queries,
            "top_k": top_k,
            "min_confidence": min_confidence,
        },
    )


async def scores(
    soc_codes: list[str],
    scenarios: list[str] | None = None,
    horizons: list[str] | None = None,
    include: list[str] | None = None,
    use_case: str | None = None,
) -> dict[str, Any]:
    """POST /v1/scores — get AI impact scores for occupations."""
    body: dict[str, Any] = {"soc_codes": soc_codes}
    if scenarios:
        body["scenarios"] = scenarios
    if horizons:
        body["horizons"] = horizons
    if include:
        body["include"] = include
    if use_case:
        body["use_case"] = use_case
    return await _request("POST", "/v1/scores", json=body)


async def portfolio(
    workforce: list[dict[str, Any]],
    scenario: str = "baseline",
    horizon: str = "3y",
    default_wage_source: str | None = None,
    include: list[str] | None = None,
) -> dict[str, Any]:
    """POST /v1/portfolio — analyze workforce portfolio impact."""
    body: dict[str, Any] = {
        "workforce": workforce,
        "scenario": scenario,
        "horizon": horizon,
    }
    if default_wage_source:
        body["default_wage_source"] = default_wage_source
    if include:
        body["include"] = include
    return await _request("POST", "/v1/portfolio", json=body)


async def skills(
    soc_codes: list[str],
    top_n: int | None = None,
    include: list[str] | None = None,
) -> dict[str, Any]:
    """POST /v1/skills — get skill importance profiles."""
    body: dict[str, Any] = {"soc_codes": soc_codes}
    if top_n is not None:
        body["top_n"] = top_n
    if include:
        body["include"] = include
    return await _request("POST", "/v1/skills", json=body)


async def occupations(
    search: str | None = None,
    soc_prefix: str | None = None,
    limit: int = 100,
    offset: int = 0,
) -> dict[str, Any]:
    """GET /v1/occupations — browse/search occupation catalog."""
    params: dict[str, Any] = {"limit": limit, "offset": offset}
    if search:
        params["search"] = search
    if soc_prefix:
        params["soc_major"] = soc_prefix
    return await _request("GET", "/v1/occupations", params=params)


async def tasks(
    soc_code: str,
    include: list[str] | None = None,
) -> dict[str, Any]:
    """GET /v1/tasks/{soc_code} — get task-level AI impact labels."""
    params: dict[str, Any] = {}
    if include:
        params["include"] = include
    return await _request("GET", f"/v1/tasks/{soc_code}", params=params)


async def meta() -> dict[str, Any]:
    """GET /v1/meta — get API metadata and version info."""
    return await _request("GET", "/v1/meta")
