from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True)
class Regression:
    name: str
    prev_status: str
    curr_status: str
    prev_risk_score: int
    curr_risk_score: int


def _status_rank(s: str) -> int:
    s = (s or "").upper()
    return {"PASSED": 0, "RISK": 1, "FAILED": 2}.get(s, 1)


def compute_trend(current_report: dict, previous_report: dict | None) -> dict:
    """Compute a best-effort trend comparison.

    Trend is designed to be resilient to older report shapes.

    Returns a dict that can be embedded into report['trend'].
    """

    if not previous_report:
        return {
            "has_previous": False,
            "regressions": [],
            "regression_count": 0,
            "endpoint_risk_prev": None,
            "endpoint_risk_delta": None,
        }

    cur_meta = current_report.get("meta") or {}
    prev_meta = previous_report.get("meta") or {}

    cur_risk = cur_meta.get("endpoint_risk_score")
    if cur_risk is None:
        cur_risk = (current_report.get("summary") or {}).get("endpoint_risk_score")

    prev_risk = prev_meta.get("endpoint_risk_score")
    if prev_risk is None:
        prev_risk = (previous_report.get("summary") or {}).get("endpoint_risk_score")

    try:
        cur_risk_i = int(cur_risk or 0)
    except Exception:
        cur_risk_i = 0
    try:
        prev_risk_i = int(prev_risk or 0)
    except Exception:
        prev_risk_i = 0

    cur_results = current_report.get("results") or []
    prev_results = previous_report.get("results") or []

    prev_by_name = {str(r.get("name")): r for r in prev_results if r.get("name") is not None}

    regressions: list[Regression] = []
    for r in cur_results:
        name = r.get("name")
        if name is None:
            continue
        name = str(name)
        prev = prev_by_name.get(name)
        if not prev:
            continue

        prev_status = str(prev.get("status") or "")
        cur_status = str(r.get("status") or "")
        prev_score = prev.get("risk_score")
        cur_score = r.get("risk_score")
        prev_score_i = int(prev_score) if isinstance(prev_score, int) else 0
        cur_score_i = int(cur_score) if isinstance(cur_score, int) else 0

        worsened_status = _status_rank(cur_status) > _status_rank(prev_status)
        worsened_score = cur_score_i > prev_score_i

        if worsened_status or worsened_score:
            regressions.append(
                Regression(
                    name=name,
                    prev_status=prev_status,
                    curr_status=cur_status,
                    prev_risk_score=prev_score_i,
                    curr_risk_score=cur_score_i,
                )
            )

    regressions.sort(key=lambda x: (x.curr_risk_score - x.prev_risk_score, _status_rank(x.curr_status)), reverse=True)

    return {
        "has_previous": True,
        "endpoint_risk_prev": prev_risk_i,
        "endpoint_risk_delta": cur_risk_i - prev_risk_i,
        "regression_count": len(regressions),
        "regressions": [
            {
                "name": x.name,
                "prev_status": x.prev_status,
                "curr_status": x.curr_status,
                "prev_risk_score": x.prev_risk_score,
                "curr_risk_score": x.curr_risk_score,
            }
            for x in regressions[:50]
        ],
    }
