"""Automatic agent selection using LLM to pick best participants."""

from __future__ import annotations

import json
from typing import TYPE_CHECKING

from src.models import AgentConfig

if TYPE_CHECKING:
    from src.llm_client import LLMClient

_MAX_RETRIES = 3


def auto_select_agents(
    topic: str,
    context: str,
    all_agents: dict[str, AgentConfig],
    client: LLMClient,
    max_agents: int = 5,
) -> list[str]:
    """PM selects the best agents for a meeting topic using LLM.

    Args:
        topic: The meeting discussion topic.
        context: Background context for the meeting.
        all_agents: All available agents to choose from.
        client: LLM client for making the selection.
        max_agents: Maximum number of agents to select.

    Returns:
        List of selected agent names.

    Raises:
        RuntimeError: When all retry attempts are exhausted.
    """
    agent_descriptions = "\n".join(
        f"- {name}: {config.role}" for name, config in all_agents.items()
    )

    system_prompt = f"""You are a meeting facilitator selecting the best participants for a discussion.

Available Agents:
{agent_descriptions}

Select up to {max_agents} agents most relevant to the topic.
Output ONLY a JSON object with these fields:
- "selected_agents": list of agent names (must be from the available agents)
- "reasoning": brief explanation of why these agents were chosen

Output ONLY the JSON object, no other text."""

    user_content = f"Topic: {topic}"
    if context:
        user_content += f"\n\nContext: {context}"

    messages: list[dict[str, str]] = [{"role": "user", "content": user_content}]
    last_error = ""

    for attempt in range(_MAX_RETRIES):
        if last_error:
            messages.append({
                "role": "user",
                "content": (
                    f"Your previous response was invalid: {last_error}. "
                    "Please output ONLY valid JSON."
                ),
            })

        raw_response = client.chat(system=system_prompt, messages=messages)

        try:
            cleaned = raw_response.strip()
            if cleaned.startswith("```"):
                cleaned = cleaned.split("\n", 1)[1] if "\n" in cleaned else cleaned
                if cleaned.endswith("```"):
                    cleaned = cleaned[:-3]
                cleaned = cleaned.strip()

            data = json.loads(cleaned)
            selected = data["selected_agents"]

            # Filter to only valid agent names
            valid_agents = [name for name in selected if name in all_agents]

            if not valid_agents:
                last_error = (
                    "No valid agents in selection. "
                    f"Choose from: {', '.join(all_agents.keys())}"
                )
                continue

            # Respect max_agents limit
            return valid_agents[:max_agents]

        except (json.JSONDecodeError, KeyError, TypeError) as exc:
            last_error = str(exc)
            continue

    raise RuntimeError(
        f"Failed to get valid agent selection after {_MAX_RETRIES} attempts. "
        f"Last error: {last_error}"
    )
