"""HTTP client helpers for EDA-first MCP adapter."""
from __future__ import annotations

import os
from typing import Any, Dict, List

import httpx

from security.auth.verifier import build_internal_auth_headers


def _eda_base_url() -> str:
    return os.getenv("EDA_BASE_URL", "http://localhost:8002").rstrip("/")


def _build_headers(
    *,
    request_id: str = "",
    caller_id: str = "",
    agent_id: str = "",
    key_id: str = "",
) -> Dict[str, str]:
    headers = build_internal_auth_headers()
    if request_id:
        headers["X-Request-Id"] = request_id
    if caller_id:
        headers["X-Caller-Id"] = caller_id
    if agent_id:
        headers["X-Agent-Id"] = agent_id
    if key_id:
        headers["X-Key-Id"] = key_id
    return headers


async def perceive(
    *,
    agent_id: str,
    input_data: Dict[str, Any],
    request_id: str = "",
    caller_id: str = "",
    key_id: str = "",
) -> Dict[str, Any]:
    headers = _build_headers(
        request_id=request_id,
        caller_id=caller_id,
        agent_id=agent_id,
        key_id=key_id,
    )
    async with httpx.AsyncClient(timeout=30.0) as client:
        resp = await client.post(
            f"{_eda_base_url()}/api/v1/agents/{agent_id}/perceive",
            json={"input_data": input_data},
            headers=headers,
        )
        resp.raise_for_status()
        return resp.json()


async def bind_norms(
    *,
    agent_id: str,
    context: Dict[str, Any],
    request_id: str = "",
    caller_id: str = "",
    key_id: str = "",
) -> Dict[str, Any]:
    headers = _build_headers(
        request_id=request_id,
        caller_id=caller_id,
        agent_id=agent_id,
        key_id=key_id,
    )
    async with httpx.AsyncClient(timeout=45.0) as client:
        resp = await client.post(
            f"{_eda_base_url()}/api/v1/agents/{agent_id}/bind_norms",
            json={"context": context},
            headers=headers,
        )
        resp.raise_for_status()
        return resp.json()


async def decide(
    *,
    agent_id: str,
    candidate_actions: List[Dict[str, Any]],
    request_id: str = "",
    caller_id: str = "",
    key_id: str = "",
) -> Dict[str, Any]:
    headers = _build_headers(
        request_id=request_id,
        caller_id=caller_id,
        agent_id=agent_id,
        key_id=key_id,
    )
    async with httpx.AsyncClient(timeout=30.0) as client:
        resp = await client.post(
            f"{_eda_base_url()}/api/v1/agents/{agent_id}/decide",
            json={"candidate_actions": candidate_actions},
            headers=headers,
        )
        resp.raise_for_status()
        return resp.json()


async def execute(
    *,
    agent_id: str,
    action: Dict[str, Any],
    request_id: str = "",
    caller_id: str = "",
    key_id: str = "",
) -> Dict[str, Any]:
    headers = _build_headers(
        request_id=request_id,
        caller_id=caller_id,
        agent_id=agent_id,
        key_id=key_id,
    )
    async with httpx.AsyncClient(timeout=30.0) as client:
        resp = await client.post(
            f"{_eda_base_url()}/api/v1/agents/{agent_id}/execute",
            json={"action": action},
            headers=headers,
        )
        resp.raise_for_status()
        return resp.json()


async def get_traces(
    *,
    agent_id: str,
    limit: int = 20,
    request_id: str = "",
    caller_id: str = "",
    key_id: str = "",
) -> List[Dict[str, Any]]:
    headers = _build_headers(
        request_id=request_id,
        caller_id=caller_id,
        agent_id=agent_id,
        key_id=key_id,
    )
    async with httpx.AsyncClient(timeout=30.0) as client:
        resp = await client.get(
            f"{_eda_base_url()}/api/v1/agents/{agent_id}/traces",
            params={"limit": limit},
            headers=headers,
        )
        resp.raise_for_status()
        return resp.json()
