from __future__ import annotations

import json
from dataclasses import dataclass
from pathlib import Path


def _html_escape(s: object) -> str:
    return (
        str(s)
        .replace("&", "&amp;")
        .replace("<", "&lt;")
        .replace(">", "&gt;")
        .replace('"', "&quot;")
        .replace("'", "&#39;")
    )


@dataclass
class EndpointRow:
    endpoint_dir: str
    endpoint: str
    run_time: str
    gate_status: str
    endpoint_risk_score: int
    decision: str
    report_relpath: str
    top_risks: list[dict]
    risk_delta: int | None = None
    regression_count: int = 0


def _latest_json_report(endpoint_dir: Path) -> Path | None:
    if not endpoint_dir.exists() or not endpoint_dir.is_dir():
        return None
    candidates = sorted(endpoint_dir.glob("*.json"), key=lambda p: p.stat().st_mtime, reverse=True)
    return candidates[0] if candidates else None


def _load_report(p: Path) -> dict | None:
    try:
        return json.loads(p.read_text(encoding="utf-8"))
    except Exception:
        return None


def write_dashboard_index(reports_dir: Path) -> str:
    """Create/overwrite a simple static index.html under reports_dir."""

    reports_dir = Path(reports_dir)
    reports_dir.mkdir(parents=True, exist_ok=True)

    rows: list[EndpointRow] = []

    for child in sorted([p for p in reports_dir.iterdir() if p.is_dir()]):
        latest = _latest_json_report(child)
        if not latest:
            continue
        rpt = _load_report(latest)
        if not rpt:
            continue

        meta = rpt.get("meta") or {}
        summary = rpt.get("summary") or {}

        endpoint_risk = meta.get("endpoint_risk_score")
        if endpoint_risk is None:
            endpoint_risk = summary.get("endpoint_risk_score", 0)

        trend = rpt.get("trend") or {}
        risk_delta = trend.get("endpoint_risk_delta") if isinstance(trend, dict) else None
        try:
            risk_delta = int(risk_delta) if risk_delta is not None else None
        except Exception:
            risk_delta = None

        regression_count = 0
        try:
            regression_count = int(trend.get("regression_count") or 0) if isinstance(trend, dict) else 0
        except Exception:
            regression_count = 0

        row = EndpointRow(
            endpoint_dir=child.name,
            endpoint=str(rpt.get("endpoint") or child.name),
            run_time=str(rpt.get("run_time") or ""),
            gate_status=str(meta.get("gate_status") or ""),
            endpoint_risk_score=int(endpoint_risk or 0),
            decision=str(meta.get("decision") or ""),
            report_relpath=str(child.name + "/" + latest.name),
            top_risks=list(summary.get("top_risks") or []),
            risk_delta=risk_delta,
            regression_count=regression_count,
        )
        rows.append(row)

    # Batch2: surface regressions first, then risk (desc), then recency.
    rows.sort(key=lambda r: (int(r.regression_count or 0), r.endpoint_risk_score, r.run_time), reverse=True)

    # Global top risks across endpoints
    global_risks = []
    for r in rows:
        for item in (r.top_risks or [])[:3]:
            global_risks.append(
                {
                    "endpoint": r.endpoint,
                    "name": item.get("name"),
                    "risk_score": item.get("risk_score"),
                    "status": item.get("status"),
                    "failure_type": item.get("failure_type"),
                    "report": r.report_relpath,
                }
            )
    global_risks.sort(key=lambda x: int(x.get("risk_score") or 0), reverse=True)
    global_risks = global_risks[:15]

    def badge(gate: str) -> str:
        gate = (gate or "").upper()
        cls = {"PASS": "pass", "WARN": "warn", "BLOCK": "block"}.get(gate, "")
        return f"<span class='gate {cls}'>{_html_escape(gate)}</span>"

    def _delta_badge(d: int | None) -> str:
        if d is None:
            return ""
        cls = "pos" if d > 0 else "neg" if d < 0 else "zero"
        sign = "+" if d > 0 else ""
        return f"<span class='delta {cls}'>{sign}{_html_escape(d)}</span>"

    endpoint_rows_html = "".join(
        "<tr>"
        f"<td>{badge(r.gate_status)}</td>"
        f"<td><code>{_html_escape(r.endpoint_risk_score)}</code> {_delta_badge(r.risk_delta)}</td>"
        f"<td><code>{_html_escape(r.regression_count)}</code></td>"
        f"<td><a href='{_html_escape(r.report_relpath)}'>{_html_escape(r.endpoint)}</a></td>"
        f"<td><code>{_html_escape(r.run_time)}</code></td>"
        f"<td><code>{_html_escape(r.decision)}</code></td>"
        "</tr>"
        for r in rows
    ) or "<tr><td colspan='6'>(no JSON reports found)</td></tr>"

    top_risks_html = "".join(
        "<tr>"
        f"<td><code>{_html_escape(x.get('risk_score'))}</code></td>"
        f"<td>{_html_escape(x.get('status'))}</td>"
        f"<td><code>{_html_escape(x.get('failure_type'))}</code></td>"
        f"<td>{_html_escape(x.get('name'))}</td>"
        f"<td><a href='{_html_escape(x.get('report'))}'>{_html_escape(x.get('endpoint'))}</a></td>"
        "</tr>"
        for x in global_risks
    ) or "<tr><td colspan='5'>(none)</td></tr>"

    css = """
    body{font-family:ui-sans-serif,system-ui,Segoe UI,Roboto,Arial; margin:20px;}
    table{border-collapse:collapse; width:100%;}
    th,td{border:1px solid #ddd; padding:8px; vertical-align:top}
    th{background:#f6f7f9; text-align:left}
    code{background:#f1f2f4; padding:1px 5px; border-radius:6px;}
    .gate{display:inline-block; padding:2px 10px; border-radius:999px; border:1px solid #aaa; font-size:12px;}
    .gate.pass{background:#e6ffed; border-color:#36b37e;}
    .gate.warn{background:#fff7e6; border-color:#ffab00;}
    .gate.block{background:#ffebe6; border-color:#ff5630;}
    .muted{color:#555}
    .delta{display:inline-block; margin-left:6px; padding:1px 8px; border-radius:999px; font-size:12px; border:1px solid #bbb;}
    .delta.pos{background:#ffebe6; border-color:#ff5630;}
    .delta.neg{background:#e6ffed; border-color:#36b37e;}
    .delta.zero{background:#f1f2f4; border-color:#bbb;}
    """

    html = f"""<!doctype html>
<html>
<head>
<meta charset='utf-8'/>
<title>AI Testing Swarm — Dashboard</title>
<style>{css}</style>
</head>
<body>
<h1>AI Testing Swarm — Dashboard</h1>
<p class='muted'>Static index generated from latest JSON report per endpoint.</p>

<h2>Endpoints</h2>
<table>
  <thead>
    <tr>
      <th>Gate</th>
      <th>Risk (Δ)</th>
      <th>Regressions</th>
      <th>Endpoint</th>
      <th>Run time</th>
      <th>Decision</th>
    </tr>
  </thead>
  <tbody>
    {endpoint_rows_html}
  </tbody>
</table>

<h2>Top risks (across endpoints)</h2>
<table>
  <thead>
    <tr>
      <th>Risk</th>
      <th>Status</th>
      <th>Failure type</th>
      <th>Test</th>
      <th>Endpoint</th>
    </tr>
  </thead>
  <tbody>
    {top_risks_html}
  </tbody>
</table>

</body>
</html>"""

    out = reports_dir / "index.html"
    out.write_text(html, encoding="utf-8")
    return str(out)
