"""
risk.py - Stage 10: risk scoring and prioritization (LLM, text-only).

Scores each validated issue 1-100, annotates it with risk_score,
recommended_priority and risk_drivers, and returns the list sorted
highest-risk first. Uses TEXT_MODEL (defaults to MODEL). On failure it falls
back to a deterministic severity-based ordering so the pipeline still produces
a prioritized list.
"""

from typing import Dict, List

from backend import config
from backend.pipeline._serialize import dumps
from backend.pipeline._stage import call_stage
from backend.prompts import RISK_SYSTEM_PROMPT, RISK_USER_INSTRUCTION

_SEV_RANK = {"critical": 90, "high": 70, "medium": 40, "low": 15}


def _ensure_ids(issues: List[Dict]) -> None:
    for i, issue in enumerate(issues, 1):
        if not issue.get("issue_id"):
            issue["issue_id"] = f"ISSUE-{i:03d}"


def score_and_prioritize(validated: List[Dict]) -> List[Dict]:
    if not validated:
        return []
    _ensure_ids(validated)

    parsed = call_stage(
        RISK_SYSTEM_PROMPT,
        RISK_USER_INSTRUCTION,
        subs={"validated_issues": dumps(validated)},
        max_tokens=config.RISK_MAX_TOKENS,
    )

    if isinstance(parsed, list):
        rows = parsed
    elif isinstance(parsed, dict):
        rows = parsed.get("prioritized_issues") or []
    else:
        rows = []
    scores: Dict[str, Dict] = {}
    for p in rows:
        if isinstance(p, dict) and p.get("issue_id"):
            scores[p["issue_id"]] = p

    for issue in validated:
        p = scores.get(issue["issue_id"])
        if p and isinstance(p.get("overall_risk_score"), (int, float)):
            issue["risk_score"] = int(p["overall_risk_score"])
            issue["recommended_priority"] = p.get("recommended_priority")
            issue["risk_drivers"] = p.get("risk_drivers") or []
        else:
            # Deterministic fallback from severity.
            issue["risk_score"] = _SEV_RANK.get(issue.get("severity"), 40)

    validated.sort(key=lambda i: i.get("risk_score", 0), reverse=True)
    print(f"[Risk] scored {len(validated)} issue(s)"
          f" ({len(scores)} from model, rest by severity)")
    return validated
