"""Tests for the meeting event loop."""

from __future__ import annotations

import json
from pathlib import Path

from src.meeting import run_meeting, save_report
from src.models import AgentConfig

SAMPLE_AGENTS: dict[str, AgentConfig] = {
    "architect": AgentConfig(name="architect", role="Software Architect", system_prompt="You are an architect."),
    "devops": AgentConfig(name="devops", role="DevOps Engineer", system_prompt="You are DevOps."),
}


class SequentialMockClient:
    """Mock client that returns different responses in sequence."""

    def __init__(self, responses: list[str]) -> None:
        self.responses = responses
        self.call_index = 0

    def chat(self, system: str, messages: list[dict[str, str]]) -> str:
        if self.call_index < len(self.responses):
            response = self.responses[self.call_index]
            self.call_index += 1
            return response
        return json.dumps({
            "analysis": "Forced finish.",
            "next_action": "FINISH",
            "final_report": "# Fallback Report",
        })


class TestRunMeeting:
    """Tests for run_meeting function."""

    def test_simple_meeting_flow(self) -> None:
        """Meeting calls one agent then finishes."""
        responses = [
            json.dumps({
                "analysis": "Need architect input.",
                "next_action": "CALL_AGENT",
                "target_agent": "architect",
                "prompt_for_agent": "What architecture?",
            }),
            "Use microservices for scalability.",
            json.dumps({
                "analysis": "Got architect input.",
                "next_action": "FINISH",
                "final_report": "# Meeting Report\n\nArchitect recommends microservices.",
            }),
        ]
        mock_client = SequentialMockClient(responses)
        report = run_meeting(topic="Database migration", agent_configs=SAMPLE_AGENTS, client=mock_client, max_rounds=5)
        assert "Meeting Report" in report
        assert "microservices" in report

    def test_max_rounds_forces_finish(self) -> None:
        """Meeting forces finish when max_rounds is reached."""
        responses = []
        for i in range(10):
            responses.append(json.dumps({
                "analysis": f"Round {i}.",
                "next_action": "CALL_AGENT",
                "target_agent": "architect",
                "prompt_for_agent": "Thoughts?",
            }))
            responses.append("Some response.")
        responses.append(json.dumps({
            "analysis": "Forced to finish.",
            "next_action": "FINISH",
            "final_report": "# Forced Report\n\nMax rounds reached.",
        }))
        mock_client = SequentialMockClient(responses)
        report = run_meeting(topic="Test", agent_configs=SAMPLE_AGENTS, client=mock_client, max_rounds=2)
        assert "Forced Report" in report or "Report" in report

    def test_meeting_with_multiple_agents(self) -> None:
        """Meeting calls multiple agents before finishing."""
        responses = [
            json.dumps({
                "analysis": "Start with architect.",
                "next_action": "CALL_AGENT",
                "target_agent": "architect",
                "prompt_for_agent": "Architecture thoughts?",
            }),
            "Use event-driven architecture.",
            json.dumps({
                "analysis": "Now DevOps.",
                "next_action": "CALL_AGENT",
                "target_agent": "devops",
                "prompt_for_agent": "Deployment concerns?",
            }),
            "Need Kubernetes.",
            json.dumps({
                "analysis": "All covered.",
                "next_action": "FINISH",
                "final_report": "# Full Report\n\nArch: event-driven. DevOps: K8s.",
            }),
        ]
        mock_client = SequentialMockClient(responses)
        report = run_meeting(topic="New system", agent_configs=SAMPLE_AGENTS, client=mock_client, max_rounds=5)
        assert "Full Report" in report


class TestSaveReport:
    """Tests for save_report function."""

    def test_save_report_creates_file(self, tmp_path: Path) -> None:
        report = "# Test Report\n\nContent here."
        path = save_report(report, topic="test-topic", output_dir=tmp_path)
        assert path.exists()
        assert path.suffix == ".md"
        assert "test-topic" in path.name
        assert path.read_text(encoding="utf-8") == report
