"""Resolve a Hunar agent id to its human-readable name.

A call row stores only the agent's UUID (`AICall.agent_variables["agent_id"]`, or
the configured `HUNAR_AGENT_ID` for older rows), which is meaningless on screen.
Hunar's Agents API is the only place the agent's name lives, so this looks it up
there — reusing `HunarProvider.list_agents()`, no new endpoint.

One list call serves every row of a Call History page, and the result is cached
briefly so opening the tab repeatedly doesn't hammer Hunar. Agents change rarely,
so a short TTL is plenty.

Never invents a name: when Hunar can't be reached the lookup returns None and the
caller shows "AI Agent information unavailable" instead of a placeholder.
"""

import logging

from django.core.cache import cache

logger = logging.getLogger(__name__)

CACHE_KEY = "hunar:agent_directory:v1"
CACHE_TTL_SECONDS = 300

#: Hunar paginates agents; one page of this size covers any realistic org here
#: (currently 4). Pagination is followed if there are more.
PAGE_SIZE = 100
MAX_PAGES = 10


def _fetch_directory() -> dict | None:
    """{agent_id: {name, agent_code, voice_persona, language, status}} or None."""
    from .providers.hunar import HunarAPIError, HunarProvider

    provider = HunarProvider()
    directory: dict[str, dict] = {}
    try:
        for page in range(1, MAX_PAGES + 1):
            payload = provider.list_agents(page=page, page_size=PAGE_SIZE)
            results = payload.get("results") if isinstance(payload, dict) else None
            for agent in (results or []):
                agent_id = str(agent.get("id") or "")
                if not agent_id:
                    continue
                directory[agent_id] = {
                    "name": str(agent.get("name") or ""),
                    "agent_code": str(agent.get("agent_code") or ""),
                    "voice_persona": str(agent.get("voice_persona") or ""),
                    "language": str(agent.get("language") or ""),
                    "status": str(agent.get("status") or ""),
                }
            if not (isinstance(payload, dict) and payload.get("next")):
                break
    except HunarAPIError as exc:
        logger.warning("[HUNAR] Could not load the agent directory: HTTP %s — %s",
                       exc.status_code, exc.message)
        return None
    except Exception:  # noqa: BLE001 — a lookup must never break a listing
        logger.exception("[HUNAR] Unexpected error loading the agent directory")
        return None
    return directory


def get_agent_directory(refresh: bool = False) -> dict:
    """Cached {agent_id: agent-info}. Empty dict when Hunar is unreachable.

    A failed fetch is NOT cached, so the next request retries rather than showing
    "unavailable" for the whole TTL after one blip.
    """
    if not refresh:
        cached = cache.get(CACHE_KEY)
        if isinstance(cached, dict):
            return cached
    directory = _fetch_directory()
    if directory is None:
        return {}
    cache.set(CACHE_KEY, directory, CACHE_TTL_SECONDS)
    return directory


def describe_agent(agent_id, directory: dict | None = None) -> dict:
    """Display fields for one agent id.

    Returns ``{"id", "name", "agent_code"}`` — `name` and `agent_code` are ""
    when the id is unknown or Hunar is unreachable, which is the caller's signal
    to render "AI Agent information unavailable".
    """
    agent_id = str(agent_id or "")
    if not agent_id:
        return {"id": "", "name": "", "agent_code": ""}
    info = (directory if directory is not None else get_agent_directory()).get(agent_id)
    if not info:
        return {"id": agent_id, "name": "", "agent_code": ""}
    return {"id": agent_id, "name": info.get("name", ""), "agent_code": info.get("agent_code", "")}
