"""Pure renderers: report dict in, HTML/Markdown/JSON string out.

No I/O and no storage access — every function takes the dict produced by the
generation side (``evaluation.report``) so rendering can be unit-tested from a
hand-built dict. Report *content* decisions (which cases pass, which rates to
show) belong to generation; this module only formats.
"""

import json
from typing import Any, Optional

from jinja2 import Template

HTML_TEMPLATE = """<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>评测报告 - {{ report.run_id }}</title>
    <style>
        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; margin: 40px; background: #f5f5f5; }
        .container { max-width: 960px; margin: 0 auto; background: #fff; padding: 32px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); }
        h1 { margin-top: 0; }
        .summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 16px; margin: 24px 0; }
        .card { background: #fafafa; border-radius: 6px; padding: 16px; text-align: center; }
        .card .value { font-size: 24px; font-weight: 700; }
        .card .label { color: #666; font-size: 14px; margin-top: 4px; }
        .case { border: 1px solid #e0e0e0; border-radius: 6px; margin: 16px 0; padding: 16px; }
        .case-title { font-weight: 600; margin-bottom: 8px; }
        .turn { background: #f9f9f9; border-radius: 4px; padding: 12px; margin: 8px 0; }
        .message-label { color: #666; font-size: 12px; }
        .rule { display: flex; align-items: center; gap: 8px; margin: 6px 0; }
        .badge { padding: 2px 8px; border-radius: 4px; font-size: 12px; }
        .pass { background: #e6f7e6; color: #2e7d32; }
        .fail { background: #ffebee; color: #c62828; }
        pre { white-space: pre-wrap; word-break: break-word; background: #f5f5f5; padding: 8px; border-radius: 4px; }
    </style>
</head>
<body>
    <div class="container">
        <h1>评测报告</h1>
        <p>评测对象：{{ report.target_name }}（{{ report.target_id }}）</p>
        <p>评测场景：{{ report.scenario_name }}（{{ report.scenario_id }}）</p>
        <p>执行时间：{{ report.started_at }} 至 {{ report.completed_at or '进行中' }}</p>

        <div class="summary">
            <div class="card">
                <div class="value">{{ report.summary.total_cases }}</div>
                <div class="label">用例总数</div>
            </div>
            <div class="card">
                <div class="value">{{ report.summary.passed_cases }}</div>
                <div class="label">通过用例</div>
            </div>
            <div class="card">
                <div class="value">{{ report.summary.total_rules }}</div>
                <div class="label">规则总数</div>
            </div>
            <div class="card">
                <div class="value">{{ "%.2f"|format(report.summary.pass_rate * 100) }}%</div>
                <div class="label">规则通过率</div>
            </div>
        </div>

        {% for case in report.cases %}
        <div class="case">
            <div class="case-title">用例 {{ case.case_id }}</div>
            {% for turn in case.turns %}
            <div class="turn">
                <div class="message-label">用户消息</div>
                <pre>{{ turn.sent_text }}</pre>
                <div class="message-label">智能体回复（{{ turn.latency_ms }}ms）</div>
                <pre>{{ turn.reply_text or '（无回复）' }}</pre>
            </div>
            {% endfor %}
            <div>
                {% for result in case.results %}
                <div class="rule">
                    <span class="badge {{ 'pass' if result.passed else 'fail' }}">{{ '通过' if result.passed else '失败' }}</span>
                    <span>{{ result.rule_type }}: {{ result.reason }}</span>
                </div>
                {% endfor %}
            </div>
        </div>
        {% endfor %}
    </div>
</body>
</html>
"""


def _pct(v: Optional[float]) -> str:
    return "—" if v is None else f"{v * 100:.1f}%"


def _ms(v: Optional[float]) -> str:
    return "—" if v is None else f"{v:.0f}ms"


def render_html(report: dict[str, Any]) -> str:
    """Render a run report dict as an HTML string."""
    return Template(HTML_TEMPLATE).render(report=report)


def render_json(report: dict[str, Any]) -> str:
    """Render a report dict as a JSON string."""
    return json.dumps(report, ensure_ascii=False, indent=2)


def render_markdown(report: dict[str, Any]) -> str:
    """Render a run report dict as Markdown."""
    s = report["summary"]
    judged_rate = s.get("judged_pass_rate")
    judged_rate_text = "—" if judged_rate is None else f"{judged_rate * 100:.1f}%"
    lines: list[str] = [
        f"# 评测报告 — {report.get('scenario_name', report.get('run_id', ''))}",
        "",
        f"**评测对象**: {report.get('target_name', '-')}  ",
        f"**评测场景**: {report.get('scenario_name', '-')}  ",
        f"**状态**: {report.get('status', '-')}  ",
        f"**开始时间**: {report.get('started_at', '-')}  ",
        f"**完成时间**: {report.get('completed_at', '-')}  ",
        "",
        "## 汇总",
        "",
        "| 指标 | 数值 |",
        "|------|------|",
        f"| 总用例数 | {s['total_cases']} |",
        f"| 通过用例 | {s['passed_cases']} |",
        f"| 失败用例 | {s['failed_cases']} |",
        f"| 总规则数 | {s['total_rules']} |",
        f"| 通过规则 | {s['passed_rules']} |",
        f"| 通过率 | {s['pass_rate'] * 100:.1f}% |",
        f"| 连通用例 | {s.get('connectivity_cases', 0)} |",
        f"| 判定型通过率 | {judged_rate_text} |",
        "",
        "## 用例明细",
        "",
    ]

    for case in report.get("cases", []):
        if case.get("connectivity"):
            badge = "🔗"
        else:
            badge = "✅" if case.get("passed") else "❌"
        title = f"### {badge} 用例 `{case['case_id']}`"
        if case.get("connectivity"):
            title += "（连通用例，未配置判定标准）"
        lines.append(title)
        lines.append("")

        for turn in case.get("turns", []):
            lines.append(f"**第 {turn['round']} 轮**")
            lines.append("")
            lines.append(f"> **用户**: {turn.get('sent_text', '—')}")
            lines.append("")
            reply = turn.get("reply_text") or "（无回复）"
            lines.append(f"> **智能体**: {reply}")
            if turn.get("latency_ms") is not None:
                lines.append(f"> *延迟: {turn['latency_ms']}ms*")
            lines.append("")

        if case.get("results"):
            lines.append("**规则评估结果**")
            lines.append("")
            lines.append("| 规则 | 结果 | 评分 | 说明 |")
            lines.append("|------|------|------|------|")
            for r in case["results"]:
                badge = "✅" if r["passed"] else "❌"
                score = f"{r['score']:.2f}" if r.get("score") is not None else "-"
                lines.append(f"| {r['rule_type']} | {badge} | {score} | {r.get('reason', '')} |")
            lines.append("")

    return "\n".join(lines)


def render_campaign_markdown(report: dict[str, Any]) -> str:
    """Render a dual-axis campaign report dict as Markdown."""
    s = report["summary"]
    lines: list[str] = [
        f"# 活动周期报告 — {report['name']}",
        "",
        f"**状态**: {report['status']}  ",
        f"**窗口**: {report['window_seconds']}s（倍速 {report['time_scale']}）  ",
        f"**开始时间**: {report['started_at'] or '-'}  ",
        f"**完成时间**: {report['completed_at'] or '-'}  ",
        "",
        "## 汇总",
        "",
        "| 指标 | 数值 |",
        "|------|------|",
        f"| 子运行总数 | {s['total_runs']} |",
        f"| 已完成 | {s['completed_runs']} |",
        f"| 整窗通过率 | {_pct(s['overall_pass_rate'])} |",
        f"| 整窗可用性 | {_pct(s['overall_availability'])} |",
        f"| 平均时延 | {_ms(s['avg_latency_ms'])} |",
        "",
        "## 时间趋势",
        "",
        "| 时段(秒) | 运行数 | 通过率 | 可用性 | 时延 |",
        "|------|------|------|------|------|",
    ]
    for b in report["time_trend"]:
        lines.append(
            f"| {b['start_seconds']:.0f}–{b['end_seconds']:.0f} | {b['run_count']} | "
            f"{_pct(b['pass_rate'])} | {_pct(b['availability'])} | {_ms(b['avg_latency_ms'])} |"
        )
    lines += [
        "",
        "## 能力汇总",
        "",
        "| 场景 | 运行数 | 通过率 | 可用性 | 时延 |",
        "|------|------|------|------|------|",
    ]
    for c in report["capability_summary"]:
        lines.append(
            f"| {c['scenario_name']} | {c['run_count']} | {_pct(c['pass_rate'])} | "
            f"{_pct(c['availability'])} | {_ms(c['avg_latency_ms'])} |"
        )
    return "\n".join(lines)
