"""HTML report generation for coderace results."""

from __future__ import annotations

import html
from datetime import datetime, timezone
from pathlib import Path

from coderace.types import Score


def generate_html_report(
    scores: list[Score],
    task_name: str = "",
    weights: dict[str, float] | None = None,
) -> str:
    """Generate a self-contained HTML report from race results."""
    ranked = sorted(scores, key=lambda s: s.composite, reverse=True)
    now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
    task_display = html.escape(task_name) if task_name else "coderace"

    rows = ""
    for i, score in enumerate(ranked, 1):
        b = score.breakdown
        cr = score.cost_result
        if cr is not None:
            cost_str = f"${cr.estimated_cost_usd:.4f}"
            if score.composite > 0:
                cost_per_pt = cr.estimated_cost_usd / score.composite
                cost_per_pt_str = f"${cost_per_pt:.5f}/pt"
            else:
                cost_per_pt_str = "N/A"
        else:
            cost_str = "-"
            cost_per_pt_str = "-"
        rows += f"""        <tr>
          <td class="rank">{i}</td>
          <td class="agent">{html.escape(score.agent)}</td>
          <td class="score">{score.composite:.1f}</td>
          <td class="{'pass' if b.tests_pass else 'fail'}">{"PASS" if b.tests_pass else "FAIL"}</td>
          <td class="{'pass' if b.exit_clean else 'fail'}">{"PASS" if b.exit_clean else "FAIL"}</td>
          <td class="{'pass' if b.lint_clean else 'fail'}">{"PASS" if b.lint_clean else "FAIL"}</td>
          <td class="num">{b.wall_time:.1f}</td>
          <td class="num">{b.lines_changed}</td>
          <td class="num">{cost_str}</td>
          <td class="num">{cost_per_pt_str}</td>
        </tr>
"""

    weights_html = ""
    if weights:
        weight_items = ", ".join(
            f"{k}: {v * 100:.0f}%" for k, v in sorted(weights.items()) if v > 0
        )
        weights_html = f'<p class="weights">Scoring: {html.escape(weight_items)}</p>'

    return f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{task_display} - coderace results</title>
<style>
  * {{ margin: 0; padding: 0; box-sizing: border-box; }}
  body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #0d1117; color: #c9d1d9; padding: 2rem; }}
  .container {{ max-width: 900px; margin: 0 auto; }}
  h1 {{ font-size: 1.5rem; margin-bottom: 0.25rem; color: #f0f6fc; }}
  .meta {{ color: #8b949e; font-size: 0.875rem; margin-bottom: 1.5rem; }}
  .weights {{ color: #8b949e; font-size: 0.8rem; margin-bottom: 1rem; }}
  table {{ width: 100%; border-collapse: collapse; background: #161b22; border-radius: 6px; overflow: hidden; }}
  th {{ background: #21262d; padding: 0.75rem 1rem; text-align: left; font-weight: 600; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; color: #8b949e; cursor: pointer; user-select: none; }}
  th:hover {{ color: #f0f6fc; }}
  th.sorted-asc::after {{ content: " \\25B2"; }}
  th.sorted-desc::after {{ content: " \\25BC"; }}
  td {{ padding: 0.75rem 1rem; border-top: 1px solid #21262d; }}
  tr:hover {{ background: #1c2128; }}
  .rank {{ text-align: center; font-weight: 700; color: #8b949e; }}
  .agent {{ font-weight: 600; color: #58a6ff; }}
  .score {{ text-align: right; font-weight: 700; color: #3fb950; font-size: 1.1em; }}
  .pass {{ text-align: center; color: #3fb950; font-weight: 600; }}
  .fail {{ text-align: center; color: #f85149; font-weight: 600; }}
  .num {{ text-align: right; font-variant-numeric: tabular-nums; }}
  footer {{ margin-top: 2rem; text-align: center; color: #484f58; font-size: 0.75rem; }}
  footer a {{ color: #58a6ff; text-decoration: none; }}
</style>
</head>
<body>
<div class="container">
  <h1>{task_display}</h1>
  <p class="meta">Generated {now}</p>
  {weights_html}
  <table id="results">
    <thead>
      <tr>
        <th data-type="num">Rank</th>
        <th data-type="str">Agent</th>
        <th data-type="num">Score</th>
        <th data-type="str">Tests</th>
        <th data-type="str">Exit</th>
        <th data-type="str">Lint</th>
        <th data-type="num">Time (s)</th>
        <th data-type="num">Lines</th>
        <th data-type="num">Cost (USD)</th>
        <th data-type="num">$/score</th>
      </tr>
    </thead>
    <tbody>
{rows}    </tbody>
  </table>
  <footer>Generated by <a href="https://github.com/mikiships/coderace">coderace</a></footer>
</div>
<script>
(function() {{
  const table = document.getElementById("results");
  const headers = table.querySelectorAll("th");
  let lastCol = -1, asc = true;
  headers.forEach((th, i) => {{
    th.addEventListener("click", () => {{
      if (lastCol === i) {{ asc = !asc; }} else {{ asc = true; lastCol = i; }}
      headers.forEach(h => h.classList.remove("sorted-asc", "sorted-desc"));
      th.classList.add(asc ? "sorted-asc" : "sorted-desc");
      const tbody = table.querySelector("tbody");
      const rows = Array.from(tbody.querySelectorAll("tr"));
      const type = th.dataset.type;
      rows.sort((a, b) => {{
        let va = a.children[i].textContent.trim();
        let vb = b.children[i].textContent.trim();
        if (type === "num") {{ va = parseFloat(va) || 0; vb = parseFloat(vb) || 0; return asc ? va - vb : vb - va; }}
        return asc ? va.localeCompare(vb) : vb.localeCompare(va);
      }});
      rows.forEach(r => tbody.appendChild(r));
    }});
  }});
}})();
</script>
</body>
</html>"""


def save_html_report(
    scores: list[Score],
    output_path: Path,
    task_name: str = "",
    weights: dict[str, float] | None = None,
) -> None:
    """Generate and save an HTML report."""
    output_path.parent.mkdir(parents=True, exist_ok=True)
    content = generate_html_report(scores, task_name=task_name, weights=weights)
    output_path.write_text(content)
