"""Meeting event loop - orchestrates the multi-agent discussion."""

from __future__ import annotations

import re
from datetime import datetime
from pathlib import Path
from typing import TYPE_CHECKING

from src.agent import format_scratchpad_summary, run_agent
from src.models import AgentConfig, MeetingState, ScratchpadEntry
from src.pm import run_pm

if TYPE_CHECKING:
    from src.llm_client import LLMClient

_COLORS = {
    "pm": "\033[1;34m",      # Bold blue
    "agent": "\033[1;32m",   # Bold green
    "system": "\033[1;33m",  # Bold yellow
    "reset": "\033[0m",
}


def _print_colored(label: str, message: str, color_key: str) -> None:
    """Print a colored message to the terminal."""
    color = _COLORS.get(color_key, "")
    reset = _COLORS["reset"]
    print(f"{color}[{label}]{reset} {message}")


def _slugify(text: str) -> str:
    """Convert text to a filename-safe slug."""
    slug = re.sub(r"[^\w\s-]", "", text.lower())
    slug = re.sub(r"[\s_]+", "-", slug)
    return slug[:50].strip("-")


def save_report(report: str, topic: str, output_dir: Path = Path("reports")) -> Path:
    """Save meeting report as a Markdown file.

    Args:
        report: The Markdown report content to save.
        topic: The meeting topic used to name the file.
        output_dir: Directory where the report file is written.

    Returns:
        The Path to the saved report file.
    """
    output_dir.mkdir(parents=True, exist_ok=True)
    timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
    slug = _slugify(topic)
    filename = f"{timestamp}-{slug}.md"
    path = output_dir / filename
    path.write_text(report, encoding="utf-8")
    return path


def run_meeting(
    topic: str,
    agent_configs: dict[str, AgentConfig],
    client: LLMClient,
    max_rounds: int = 5,
    output_dir: Path = Path("reports"),
) -> str:
    """Execute the full meeting loop.

    1. Initialize MeetingState with topic.
    2. Loop: PM decides, Agent responds, whiteboard updates.
    3. Force finish if max_rounds reached.

    Args:
        topic: The discussion topic for the meeting.
        agent_configs: Map of agent name to AgentConfig for all participants.
        client: LLM client used by both PM and agents.
        max_rounds: Maximum number of PM decision rounds before forcing a finish.
        output_dir: Directory to save the final report (unused here; caller may use).

    Returns:
        The final Markdown report string produced by the PM.
    """
    state = MeetingState(topic=topic, max_rounds=max_rounds)

    _print_colored("SYSTEM", f"Meeting started: {topic}", "system")
    _print_colored("SYSTEM", f"Participants: {', '.join(agent_configs.keys())}", "system")
    print()

    while state.current_round < state.max_rounds:
        state.current_round += 1
        _print_colored("SYSTEM", f"--- Round {state.current_round}/{state.max_rounds} ---", "system")

        if state.current_round == state.max_rounds:
            force_entry = ScratchpadEntry(
                agent_name="SYSTEM",
                content="MAX ROUNDS REACHED. You MUST set next_action to FINISH and provide a final_report.",
                timestamp=datetime.now(),
            )
            state.scratchpad.append(force_entry)

        decision = run_pm(state, agent_configs, client)
        _print_colored("PM", f"Analysis: {decision.analysis}", "pm")

        if decision.next_action == "FINISH":
            _print_colored("PM", "Meeting concluded.", "pm")
            print()
            report = decision.final_report or "# Meeting Report\n\nNo report generated."
            return report

        target_name = decision.target_agent
        target_config = agent_configs[target_name]
        _print_colored("PM", f"Calling {target_name}: {decision.prompt_for_agent}", "pm")

        scratchpad_summary = format_scratchpad_summary(state.scratchpad)
        agent_response = run_agent(
            config=target_config,
            prompt=decision.prompt_for_agent,
            scratchpad_summary=scratchpad_summary,
            client=client,
        )

        _print_colored(target_name.upper(), agent_response, "agent")
        print()

        entry = ScratchpadEntry(
            agent_name=target_name,
            content=agent_response,
            timestamp=datetime.now(),
        )
        state.scratchpad.append(entry)

    return "# Meeting Report\n\nMeeting ended after maximum rounds without PM conclusion."
