"""Markdown reporter for human-readable output."""

from __future__ import annotations

from datetime import datetime

from mcp_stress_test.core.protocols import AttackResult, ChainResult, ReportFormat
from mcp_stress_test.reporters.base import BaseReporter, ReportMetrics


class MarkdownReporter(BaseReporter):
    """Markdown format reporter."""

    @property
    def name(self) -> str:
        return "markdown"

    @property
    def format(self) -> ReportFormat:
        return ReportFormat.MARKDOWN

    @property
    def file_extension(self) -> str:
        return "md"

    def _render(
        self,
        results: list[AttackResult],
        chain_results: list[ChainResult] | None,
        metrics: ReportMetrics,
    ) -> str:
        """Render Markdown report."""
        lines = [
            "# MCP Stress Test Report",
            "",
            f"*Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*",
            "",
            "## Summary",
            "",
            f"- **Total Tests**: {metrics.total_tests}",
            f"- **Detection Rate**: {metrics.detection_rate:.1f}%",
            f"- **Evasion Rate**: {metrics.evasion_rate:.1f}%",
            f"- **Avg Scan Time**: {metrics.avg_scan_time_ms:.2f}ms",
            "",
            "## Results by Strategy",
            "",
            "| Strategy | Detected | Missed | Rate |",
            "|----------|----------|--------|------|",
        ]

        for strategy, data in metrics.by_strategy.items():
            detected = data["detected"]
            missed = data["missed"]
            total = detected + missed
            rate = detected / total * 100 if total > 0 else 0
            lines.append(f"| {strategy} | {detected} | {missed} | {rate:.1f}% |")

        lines.extend(
            [
                "",
                "## Results by Tool",
                "",
                "| Tool | Detected | Missed | Rate |",
                "|------|----------|--------|------|",
            ]
        )

        for tool, data in metrics.by_tool.items():
            detected = data["detected"]
            missed = data["missed"]
            total = detected + missed
            rate = detected / total * 100 if total > 0 else 0
            lines.append(f"| {tool} | {detected} | {missed} | {rate:.1f}% |")

        if chain_results:
            lines.extend(
                [
                    "",
                    "## Attack Chains",
                    "",
                    "| Chain | Steps | Detected | Rate | Status |",
                    "|-------|-------|----------|------|--------|",
                ]
            )

            for cr in chain_results:
                status = "✅ Blocked" if cr.chain_detected else "❌ Evaded"
                lines.append(
                    f"| {cr.chain_name} | {len(cr.steps)} | "
                    f"{cr.steps_detected} | {cr.detection_rate:.1f}% | {status} |"
                )

        # Detailed results (limited to first 20)
        lines.extend(
            [
                "",
                "## Detailed Results",
                "",
                "<details>",
                "<summary>Click to expand (showing first 20)</summary>",
                "",
                "| Tool | Strategy | Score Δ | Detected | Threats |",
                "|------|----------|---------|----------|---------|",
            ]
        )

        for r in results[:20]:
            status = "✅" if r.detected else "❌"
            threats = ", ".join(r.threats_found[:2]) if r.threats_found else "-"
            lines.append(
                f"| {r.tool_name} | {r.strategy} | {r.score_delta:+.1f} | {status} | {threats} |"
            )

        if len(results) > 20:
            lines.append(f"| ... | ... | ... | ... | *{len(results) - 20} more* |")

        lines.extend(
            [
                "",
                "</details>",
                "",
                "---",
                "",
                "*Generated by [MCP Stress Test Framework](https://github.com/mcp-tool-shop/mcp-stress-test)*",
            ]
        )

        return "\n".join(lines)
