"""
Evaluation Report Generation

Generates human-readable reports from benchmark results.
"""

import json
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path

from sage.evaluation.benchmark import BenchmarkResult


@dataclass
class ReportConfig:
    """Configuration for report generation."""

    include_details: bool = True
    include_failed_only: bool = False
    max_response_preview: int = 200
    output_format: str = "markdown"  # markdown, json, html


class ReportGenerator:
    """
    Generates evaluation reports from benchmark results.

    Produces human-readable summaries with detailed breakdowns.
    """

    def __init__(self, config: ReportConfig | None = None):
        """Initialize report generator."""
        self.config = config or ReportConfig()

    def generate(self, result: BenchmarkResult) -> str:
        """
        Generate a report from benchmark result.

        Args:
            result: Benchmark result to report on

        Returns:
            Formatted report string
        """
        if self.config.output_format == "json":
            return self._generate_json(result)
        elif self.config.output_format == "html":
            return self._generate_html(result)
        else:
            return self._generate_markdown(result)

    def _generate_markdown(self, result: BenchmarkResult) -> str:
        """Generate Markdown report."""
        lines = []

        # Header
        lines.append(f"# Benchmark Report: {result.dataset_name}")
        lines.append(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        lines.append("")

        # Summary
        lines.append("## Summary")
        lines.append("")
        total = result.total_questions
        passed = result.questions_passed
        pass_rate = passed / total if total > 0 else 0
        lines.append(f"- **Total Questions**: {total}")
        lines.append(f"- **Passed**: {passed} ({pass_rate:.1%})")
        lines.append(f"- **Failed**: {result.questions_failed}")
        lines.append(f"- **Errors**: {result.questions_errored}")
        lines.append("")

        # Key Metrics
        lines.append("## Key Metrics")
        lines.append("")
        lines.append("| Metric | Value |")
        lines.append("|--------|-------|")
        lines.append(f"| Accuracy | {result.accuracy:.1%} |")
        lines.append(f"| Citation F1 | {result.avg_citation_f1:.3f} |")
        lines.append(f"| Retrieval Precision | {result.avg_retrieval_precision:.3f} |")
        lines.append(f"| Avg Latency | {result.avg_latency_ms:.0f}ms |")
        lines.append(f"| Avg Tokens | {result.avg_tokens:.0f} |")
        lines.append("")

        # By Category
        if result.by_category:
            lines.append("## Results by Category")
            lines.append("")
            lines.append("| Category | Count | Accuracy | Passed |")
            lines.append("|----------|-------|----------|--------|")
            for cat, stats in result.by_category.items():
                lines.append(
                    f"| {cat} | {stats['count']} | {stats['accuracy']:.1%} | {stats['passed']} |"
                )
            lines.append("")

        # By Difficulty
        if result.by_difficulty:
            lines.append("## Results by Difficulty")
            lines.append("")
            lines.append("| Difficulty | Count | Accuracy | Passed |")
            lines.append("|------------|-------|----------|--------|")
            for diff, stats in result.by_difficulty.items():
                lines.append(
                    f"| {diff} | {stats['count']} | {stats['accuracy']:.1%} | {stats['passed']} |"
                )
            lines.append("")

        # Detailed Results
        if self.config.include_details:
            lines.append("## Detailed Results")
            lines.append("")

            for qr in result.results:
                if self.config.include_failed_only and qr.passed:
                    continue

                lines.append(f"### {qr.question.id}")
                lines.append("")
                lines.append(f"**Question**: {qr.question.question}")
                lines.append("")
                lines.append(f"**Status**: {'PASSED' if qr.passed else 'FAILED'}")
                if qr.error:
                    lines.append(f"**Error**: {qr.error}")

                if qr.response:
                    preview = qr.response.answer[:self.config.max_response_preview]
                    if len(qr.response.answer) > self.config.max_response_preview:
                        preview += "..."
                    lines.append(f"**Response Preview**: {preview}")

                lines.append("")
                lines.append(f"- Correctness: {qr.metrics.answer.correctness_score:.1%}")
                lines.append(f"- Citation F1: {qr.metrics.citation.f1:.3f}")
                lines.append(f"- Retrieval Precision: {qr.metrics.retrieval.precision_at_k:.3f}")
                lines.append(f"- Latency: {qr.metrics.latency_ms:.0f}ms")
                lines.append("")
                lines.append("---")
                lines.append("")

        return "\n".join(lines)

    def _generate_json(self, result: BenchmarkResult) -> str:
        """Generate JSON report."""
        return json.dumps(result.to_dict(), indent=2)

    def _generate_html(self, result: BenchmarkResult) -> str:
        """Generate HTML report."""
        lines = []

        lines.append("<!DOCTYPE html>")
        lines.append("<html><head>")
        lines.append(f"<title>Benchmark Report: {result.dataset_name}</title>")
        lines.append("<style>")
        lines.append("body { font-family: Arial, sans-serif; margin: 40px; }")
        lines.append("table { border-collapse: collapse; width: 100%; }")
        lines.append("th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }")
        lines.append("th { background-color: #f2f2f2; }")
        lines.append(".passed { color: green; }")
        lines.append(".failed { color: red; }")
        lines.append("</style>")
        lines.append("</head><body>")

        lines.append(f"<h1>Benchmark Report: {result.dataset_name}</h1>")

        # Summary
        lines.append("<h2>Summary</h2>")
        total = result.total_questions
        passed = result.questions_passed
        pass_rate = passed / total if total > 0 else 0
        lines.append(f"<p><strong>Total Questions:</strong> {total}</p>")
        lines.append(f"<p><strong>Passed:</strong> {passed} ({pass_rate:.1%})</p>")
        lines.append(f"<p><strong>Failed:</strong> {result.questions_failed}</p>")

        # Metrics table
        lines.append("<h2>Key Metrics</h2>")
        lines.append("<table>")
        lines.append("<tr><th>Metric</th><th>Value</th></tr>")
        lines.append(f"<tr><td>Accuracy</td><td>{result.accuracy:.1%}</td></tr>")
        lines.append(f"<tr><td>Citation F1</td><td>{result.avg_citation_f1:.3f}</td></tr>")
        lines.append(f"<tr><td>Retrieval Precision</td><td>{result.avg_retrieval_precision:.3f}</td></tr>")
        lines.append(f"<tr><td>Avg Latency</td><td>{result.avg_latency_ms:.0f}ms</td></tr>")
        lines.append("</table>")

        lines.append("</body></html>")

        return "\n".join(lines)

    def save(self, result: BenchmarkResult, path: Path) -> None:
        """
        Save report to file.

        Args:
            result: Benchmark result
            path: Output path
        """
        report = self.generate(result)
        with open(path, "w") as f:
            f.write(report)


def generate_summary_report(result: BenchmarkResult) -> str:
    """
    Generate a brief summary report.

    Args:
        result: Benchmark result

    Returns:
        Summary string
    """
    total = result.total_questions
    passed = result.questions_passed
    pass_rate = passed / total if total > 0 else 0

    return f"""
SAGE RAG Benchmark Summary
==========================
Dataset: {result.dataset_name}
Date: {result.timestamp}

Results: {passed}/{total} passed ({pass_rate:.1%})
Accuracy: {result.accuracy:.1%}
Citation F1: {result.avg_citation_f1:.3f}
Retrieval Precision: {result.avg_retrieval_precision:.3f}
Avg Latency: {result.avg_latency_ms:.0f}ms
""".strip()
