"""HTTP clients for Normbase and EDA services."""
from __future__ import annotations

import os
import uuid
from typing import Any, Dict, List

import httpx

from security.auth.verifier import build_internal_auth_headers


def _normbase_base_url() -> str:
    return os.getenv("NORMBASE_BASE_URL", "http://localhost:8001").rstrip("/")


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


async def retrieve_norms(
    context: Dict[str, Any],
    agent_role: str,
    top_k: int = 20,
    field_ids: List[str] | None = None,
    request_id: str = "",
    caller_id: str = "",
    agent_id: str = "",
    key_id: str = "",
) -> Dict[str, Any]:
    payload = {
        "context": context,
        "agent_role": agent_role,
        "top_k": top_k,
    }
    if field_ids:
        payload["field_ids"] = field_ids
    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
    async with httpx.AsyncClient(timeout=45.0) as client:
        resp = await client.post(
            f"{_normbase_base_url()}/api/v1/retrieve",
            json=payload,
            headers=headers,
        )
        resp.raise_for_status()
        return resp.json()


async def get_agent_field_ids(agent_id: str) -> List[str]:
    """Fetch EDA active_fields and keep only UUID-like field IDs."""
    if not agent_id:
        return []
    headers = build_internal_auth_headers()
    async with httpx.AsyncClient(timeout=20.0) as client:
        resp = await client.get(
            f"{_eda_base_url()}/api/v1/agents/{agent_id}",
            headers=headers,
        )
        resp.raise_for_status()
        data = resp.json() or {}
    raw_fields = data.get("active_fields") or []
    field_ids: List[str] = []
    for value in raw_fields:
        text = str(value).strip()
        if not text:
            continue
        try:
            field_ids.append(str(uuid.UUID(text)))
        except ValueError:
            continue
    return field_ids


async def suggest_roles(
    context: Dict[str, Any],
    field_ids: List[str] | None = None,
    top_k: int = 5,
    request_id: str = "",
    caller_id: str = "",
    agent_id: str = "",
    key_id: str = "",
) -> Dict[str, Any]:
    """Call Normbase role suggestion endpoint."""
    payload: Dict[str, Any] = {
        "context": context,
        "top_k": top_k,
    }
    if field_ids:
        payload["field_ids"] = field_ids
    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
    async with httpx.AsyncClient(timeout=30.0) as client:
        resp = await client.post(
            f"{_normbase_base_url()}/api/v1/roles/suggest",
            json=payload,
            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]:
    payload = {"context": context}
    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
    async with httpx.AsyncClient(timeout=90.0) as client:
        resp = await client.post(
            f"{_eda_base_url()}/api/v1/agents/{agent_id}/bind_norms",
            json=payload,
            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_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
    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()

