"""Tests for colony reporting."""

import pytest

from fliiq.runtime.colony.models import (
    AgentReflection,
    AgentRole,
    ColonyState,
    GovernanceDecision,
    IntelBrief,
    Proposal,
    ProposalStatus,
    ProposalType,
    QAMetrics,
    RiskLevel,
    TimelineEntry,
    Vote,
    VotePosition,
)
from fliiq.runtime.colony.reporting import ReportGenerator
from fliiq.runtime.colony.state import StateManager


@pytest.fixture()
def state(tmp_path):
    sm = StateManager(tmp_path)
    sm.ensure_dirs()
    return sm


@pytest.fixture()
def populated_state(state):
    """State with sample data for report generation."""
    # Colony state
    state.save_colony_state(ColonyState(
        experiment_id=1,
        branch_name="colony/experiment-001",
        status="stopped",
        cycle_count=10,
    ))

    # Intel briefs
    state.save_intel_brief(IntelBrief(
        id="INTEL-RPT001",
        title="Claude 4.7 announced",
        source_type="blog",
        relevance="direct",
        summary="Anthropic released Claude 4.7 with improved tool use.",
        implications=["Could improve Fliiq's agent reliability"],
    ))

    # Proposals
    state.save_proposal(Proposal(
        id="PROP-RPT001",
        title="Upgrade to Claude 4.7",
        type=ProposalType.MODEL_CONFIG,
        risk=RiskLevel.LOW,
        proposer=AgentRole.RESEARCH,
        status=ProposalStatus.IMPLEMENTED,
        description="Update default model to Claude 4.7 for better tool use.",
        motivation="INTEL-RPT001 shows significant improvement.",
    ))

    # Votes
    state.save_vote(Vote(
        proposal_id="PROP-RPT001",
        voter=AgentRole.QA,
        position=VotePosition.SUPPORT,
        reasoning="Tests pass with new model. No regressions.",
    ))
    state.save_vote(Vote(
        proposal_id="PROP-RPT001",
        voter=AgentRole.SCOUT,
        position=VotePosition.SUPPORT,
        reasoning="Users want better reliability.",
    ))

    # Decision
    state.append_decision(GovernanceDecision(
        proposal_id="PROP-RPT001",
        outcome=ProposalStatus.APPROVED,
        reasoning="Unanimous support, low risk, clear evidence.",
        commit_sha="abc123",
    ))

    # Timeline
    state.append_timeline(TimelineEntry(agent="intelligence", action="Found Claude 4.7 release"))
    state.append_timeline(TimelineEntry(agent="research", action="Drafted PROP-RPT001"))
    state.append_timeline(TimelineEntry(agent="governance", action="Approved PROP-RPT001"))

    # Metrics
    state.save_metrics(QAMetrics(test_count=520, pass_count=520, fail_count=0, lint_issues=0))

    # Reflections
    state.append_reflection(AgentReflection(
        agent=AgentRole.INTELLIGENCE,
        cycle_number=1,
        observation="Found Claude 4.7 release",
        action_taken="Created brief INTEL-RPT001",
        outcome="High-relevance finding",
        lesson="Anthropic blog is the best source for model updates",
    ))

    return state


class TestReportGenerator:
    def test_generates_report_file(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        report_path = gen.generate_session_report(1)
        assert report_path.exists()
        assert report_path.name == "session-001.md"

    def test_report_contains_summary(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_session_report(1)
        content = path.read_text()
        assert "Experiment 1" in content
        assert "colony/experiment-001" in content

    def test_report_contains_timeline(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_session_report(1)
        content = path.read_text()
        assert "Timeline" in content
        assert "intelligence" in content.lower()

    def test_report_contains_intel(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_session_report(1)
        content = path.read_text()
        assert "INTEL-RPT001" in content
        assert "Claude 4.7" in content

    def test_report_contains_debate(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_session_report(1)
        content = path.read_text()
        assert "PROP-RPT001" in content
        assert "SUPPORT" in content
        assert "Unanimous support" in content

    def test_report_contains_reflections(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_session_report(1)
        content = path.read_text()
        assert "Agent Evolution" in content
        assert "Anthropic blog" in content

    def test_report_contains_metrics(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_session_report(1)
        content = path.read_text()
        assert "520" in content


class TestDebateThread:
    def test_debate_thread(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        thread = gen.generate_debate_thread("PROP-RPT001")
        assert "Upgrade to Claude 4.7" in thread
        assert "SUPPORT" in thread
        assert "abc123" in thread

    def test_debate_thread_not_found(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        thread = gen.generate_debate_thread("PROP-NOPE")
        assert "not found" in thread


class TestTimelineMarkdown:
    def test_timeline_markdown(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        md = gen.generate_timeline_markdown()
        assert "intelligence" in md
        assert "research" in md

    def test_empty_timeline(self, state, tmp_path):
        gen = ReportGenerator(state, tmp_path)
        md = gen.generate_timeline_markdown()
        assert "No timeline" in md


class TestHtmlReport:
    def test_generates_html_file(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_html_report(1)
        assert path.exists()
        assert path.name == "session-001.html"

    def test_html_contains_doctype(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_html_report(1)
        content = path.read_text()
        assert "<!DOCTYPE html>" in content
        assert "</html>" in content

    def test_html_contains_proposal(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_html_report(1)
        content = path.read_text()
        assert "PROP-RPT001" in content
        assert "Upgrade to Claude 4.7" in content

    def test_html_contains_votes(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_html_report(1)
        content = path.read_text()
        assert "SUPPORT" in content
        assert "Tests pass" in content

    def test_html_contains_decision(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_html_report(1)
        content = path.read_text()
        assert "APPROVED" in content
        assert "abc123" in content

    def test_html_contains_intel(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_html_report(1)
        content = path.read_text()
        assert "INTEL-RPT001" in content
        assert "Claude 4.7" in content

    def test_html_contains_timeline(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_html_report(1)
        content = path.read_text()
        assert "Timeline" in content
        assert "intelligence" in content

    def test_html_contains_metrics(self, populated_state, tmp_path):
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_html_report(1)
        content = path.read_text()
        assert "520" in content

    def test_html_self_contained(self, populated_state, tmp_path):
        """No external CSS/JS references."""
        gen = ReportGenerator(populated_state, tmp_path)
        path = gen.generate_html_report(1)
        content = path.read_text()
        assert "<style>" in content
        assert "href=" not in content  # no external stylesheets
        assert "<script" not in content  # no javascript
