from backend.agents.agent_connect_v2 import (
    AgentConnect,
    DSSToolAgent,
)
from backend.config import (
    get_conversation_vision_llm,
    get_default_llm_id,
    get_extraction_mode,
)
from backend.constants import ExtractionMode
from backend.utils.conv_utils import get_selected_agents_as_objs
from backend.utils.llm_utils import get_llm_display_name
from backend.utils.logging_utils import (
    get_logger,
)

logger = get_logger(__name__)


def _current_date() -> str:
    import datetime

    return datetime.date.today().strftime("%Y-%m-%d")


# =============================================================================
#  BUILD AgentConnect
# =============================================================================
def build_orchestrator(
    store,
    agent_ids,
    *,
    base_model: str | None = None,
    enterprise_agents_by_id: dict[str, dict] | None = None,
    user_agents: dict | None = None,
    doc_generation_enabled: bool | None = None,
    agent_chat_mode: bool = False,
):
    """
    Build AgentConnect from the exact agent subset selected for this turn.

    User agents are expected to be preloaded by the caller so this helper can stay
    focused on translating already-authorized agent payloads into DSS tool agents.

    Args:
        store: User-scoped store used by downstream helpers when shaping agent objects.
        agent_ids: Selected agent ids to expose through AgentConnect for this turn only.
        enterprise_agents_by_id: Optional pre-resolved enterprise agents keyed by id.
        user_agents: Optional preloaded full user-agent payloads keyed by id.
        agent_chat_mode: Build the single Agent Chat target without catalog lookup.
    """
    logger.debug("build_orchestrator called with agent_ids=%s", agent_ids)
    if agent_chat_mode:
        # Agent Chat bypasses the Agent Hub catalog: it has either no agent tool or its selected main agent.
        items = []
        if agent_ids:
            agent_id = agent_ids[0]
            try:
                agent_name = get_llm_display_name(agent_id)
            except Exception:
                logger.exception("Failed to load Agent Chat agent name for %s", agent_id)
                agent_name = agent_id
            items.append(
                DSSToolAgent(
                    dss_agent_id=agent_id,
                    agent_system_instructions=f"Today is {_current_date()}.",
                    tool_agent_description="The default tool for every request, including ones you could answer yourself from your own "
                    "knowledge (facts, math, greetings, opinions, general questions). Always call this tool unless the "
                    "request is specifically for a downloadable DOCX/PPTX to be created, or for revising, editing, or "
                    "converting an existing Agent Hub-generated DOCX/PPTX, and document tools are available for that. "
                    "Reading, analyzing, or summarizing an attached file is NOT a document-tool case and should still "
                    "use this tool. Knowing the answer yourself is never a reason to skip this tool. When in doubt, "
                    "use this tool.",
                    agent_name=agent_name or agent_id,
                )
            )
        return AgentConnect(
            base_model=base_model or get_default_llm_id(),
            agents=items,
            store=store,
            doc_generation_enabled=doc_generation_enabled,
        )

    items: list[DSSToolAgent] = []
    agents_objs = get_selected_agents_as_objs(
        store,
        agent_ids,
        enterprise_agents_by_id=enterprise_agents_by_id,
        user_agents=user_agents,
    )
    current_date = _current_date()
    for agent in agents_objs:
        # Enterprise agents always expose this field; their description is optional.
        if "agent_system_instructions" in agent:
            items.append(
                DSSToolAgent(
                    dss_agent_id=agent["id"],
                    agent_system_instructions=f"Today is {current_date}. {agent['agent_system_instructions']}",
                    tool_agent_description=agent["tool_agent_description"],
                    agent_name=agent["name"],
                )
            )
        else:
            # User agent
            items.append(
                DSSToolAgent(
                    dss_agent_id=agent.get("id"),
                    agent_system_instructions=f"Today is {current_date}. {agent.get('system_prompt', '')}",
                    tool_agent_description=agent.get("description") or "",
                    agent_name=agent.get("name") or "Unnamed Agent",
                )
            )

    return AgentConnect(
        base_model=base_model or get_default_llm_id(),
        agents=items,
        store=store,
        doc_generation_enabled=doc_generation_enabled,
    )


def build_agent(
    store=None,
    msgs: list[dict] | None = None,
    *,
    base_model: str | None = None,
    doc_generation_enabled: bool | None = None,
):
    # First Check if we should use Vision LLM for screenshots
    # Determine if any messages have documents with snapshots
    msgs = msgs or []
    has_snapshots = False
    for message in msgs:
        docs = message.get("__documents__") or []
        for doc in docs:
            snapshots = doc.get("snapshots") or []
            if snapshots:
                has_snapshots = True
                break
        if has_snapshots:
            break

    # Use Vision LLM if extraction mode is pagesScreenshots and there are snapshots
    extraction_mode = get_extraction_mode()
    if extraction_mode == ExtractionMode.PAGES_SCREENSHOTS and has_snapshots:
        base_model = get_conversation_vision_llm()
    elif not base_model:
        base_model = get_default_llm_id()
    return AgentConnect(
        base_model=base_model,
        agents=None,
        store=store,
        doc_generation_enabled=doc_generation_enabled,
    )
