"""Report generator — JSON results → markdown tables."""

from __future__ import annotations

import json
from pathlib import Path
from typing import Any


def load_results(results_dir: str | Path) -> list[dict[str, Any]]:
    """Load all JSON result files from a directory."""
    results_dir = Path(results_dir)
    all_results: list[dict[str, Any]] = []
    for path in sorted(results_dir.glob("bench_*.json")):
        data = json.loads(path.read_text())
        all_results.append(data)
    return all_results


def _fmt_ms(val: float) -> str:
    """Format milliseconds for display."""
    if val == 0.0:
        return "—"
    if val < 1.0:
        return f"{val:.2f}ms"
    if val < 1000.0:
        return f"{val:.1f}ms"
    return f"{val / 1000:.2f}s"


def _fmt_cell(result: dict[str, Any]) -> str:
    """Format a single result cell showing p50 (p95)."""
    if result.get("skipped"):
        return "N/A"
    if result.get("error"):
        return "ERR"
    p50 = result.get("p50", 0.0)
    p95 = result.get("p95", 0.0)
    return f"{_fmt_ms(p50)} ({_fmt_ms(p95)})"


def generate_markdown(all_runs: list[dict[str, Any]]) -> str:
    """Generate a markdown report from benchmark results.

    Groups by scale, then creates a comparison table per scale level.
    """
    lines: list[str] = []
    lines.append("# Piggie Benchmark Results\n")

    # Group runs by scale
    by_scale: dict[str, list[dict[str, Any]]] = {}
    for run in all_runs:
        scale = run.get("scale", "unknown")
        by_scale.setdefault(scale, []).append(run)

    for scale, runs in sorted(by_scale.items()):
        lines.append(f"## Scale: {scale.upper()}\n")

        # System info from first run
        sys_info = runs[0].get("system_info", {})
        if sys_info:
            lines.append("**System:**")
            lines.append(f"- Platform: {sys_info.get('platform', 'N/A')}")
            lines.append(f"- CPUs: {sys_info.get('cpu_count', 'N/A')}")
            lines.append(f"- RAM: {sys_info.get('memory_gb', 'N/A')} GB")
            lines.append(f"- Python: {sys_info.get('python_version', 'N/A')}")
            lines.append("")

        # Collect all databases and workloads from these runs
        db_results: dict[str, dict[str, dict[str, Any]]] = {}
        workload_ids: list[str] = []

        for run in runs:
            for r in run.get("results", []):
                db = r["db"]
                wid = r["workload_id"]
                if db not in db_results:
                    db_results[db] = {}
                db_results[db][wid] = r
                if wid not in workload_ids:
                    workload_ids.append(wid)

        dbs = sorted(db_results.keys())

        if not dbs:
            lines.append("No results.\n")
            continue

        # Summary table: p50 (p95)
        lines.append("### Latency — p50 (p95)\n")
        header = "| Workload | " + " | ".join(dbs) + " |"
        sep = "|" + "---|" * (len(dbs) + 1)
        lines.append(header)
        lines.append(sep)

        for wid in workload_ids:
            row = f"| {wid} |"
            for db in dbs:
                r = db_results.get(db, {}).get(wid)
                if r:
                    row += f" {_fmt_cell(r)} |"
                else:
                    row += " — |"
            lines.append(row)

        lines.append("")

        # Detail table: all stats
        lines.append("### Detailed Statistics\n")
        header2 = "| Workload | DB | p50 | p95 | p99 | Mean | StdDev | Result |"
        sep2 = "|---|---|---|---|---|---|---|---|"
        lines.append(header2)
        lines.append(sep2)

        for wid in workload_ids:
            for db in dbs:
                r = db_results.get(db, {}).get(wid)
                if not r:
                    continue
                if r.get("skipped"):
                    lines.append(
                        f"| {wid} | {db} | N/A | N/A | N/A | N/A | N/A "
                        f"| {r.get('skip_reason', 'skipped')} |"
                    )
                elif r.get("error"):
                    lines.append(
                        f"| {wid} | {db} | ERR | ERR | ERR | ERR | ERR "
                        f"| {r['error'][:60]} |"
                    )
                else:
                    rv = r.get("result_value", "")
                    if isinstance(rv, (list, dict)):
                        rv = f"{len(rv) if isinstance(rv, list) else 'obj'} items"
                    lines.append(
                        f"| {wid} | {db} "
                        f"| {_fmt_ms(r['p50'])} "
                        f"| {_fmt_ms(r['p95'])} "
                        f"| {_fmt_ms(r['p99'])} "
                        f"| {_fmt_ms(r['mean'])} "
                        f"| {_fmt_ms(r['stddev'])} "
                        f"| {rv} |"
                    )

        lines.append("")

    lines.append("---\n")
    lines.append("*Generated by `python -m benchmarks report`*\n")

    return "\n".join(lines)


def write_report(
    results_dir: str | Path,
    reports_dir: str | Path | None = None,
) -> Path:
    """Load results and write a markdown report."""
    results_dir = Path(results_dir)
    if reports_dir is None:
        reports_dir = results_dir.parent / "reports"
    reports_dir = Path(reports_dir)
    reports_dir.mkdir(parents=True, exist_ok=True)

    all_runs = load_results(results_dir)
    if not all_runs:
        raise FileNotFoundError(f"No benchmark result files found in {results_dir}")

    md = generate_markdown(all_runs)
    out_path = reports_dir / "benchmark_report.md"
    out_path.write_text(md)
    return out_path
