from __future__ import annotations
from .schemas import Finding, ScanResult

SEVERITY_MULTIPLIER = {
    "good": 0.0,
    "normal": 0.0,
    "notgood": 1.0,
    "bad": 3.0,
    "serious": 9.0,
    "info": 0.0,
}

# score >= threshold -> rank
RANK_THRESHOLDS: list[tuple[float, str]] = [
    (99.0, "SSS"),
    (95.0, "SS"),
    (90.0, "S"),
    (85.0, "A"),
    (80.0, "B"),
    (75.0, "C"),
    (70.0, "D"),
    (65.0, "E"),
    (60.0, "F"),
    (55.0, "G"),
    (50.0, "H"),
    (45.0, "I"),
    (40.0, "J"),
    (35.0, "K"),
    (30.0, "L"),
    (25.0, "M"),
    (20.0, "N"),
    (15.0, "O"),
    (10.0, "P"),
    (5.0, "Q"),
]

RANK_COLOR = {
    "SSS": "bright-green",
    "SS": "bright-green",
    "S": "bright-green",
    "A": "green",
    "B": "green",
    "C": "green",
    "D": "bright-yellow",
    "E": "bright-yellow",
    "F": "bright-yellow",
    "G": "yellow",
    "H": "yellow",
    "I": "yellow",
    "J": "bright-orange",
    "K": "bright-orange",
    "L": "bright-orange",
    "M": "orange",
    "N": "orange",
    "O": "bright-red",
    "P": "bright-red",
    "Q": "red",
    "R": "purple",
}


def compute_score(findings: list[Finding]) -> float:
    penalty = 0.0
    for f in findings:
        penalty += SEVERITY_MULTIPLIER.get(f.severity, 0.0) * float(f.weight)
    score = 100.0 - penalty
    if score < 0:
        score = 0.0
    if score > 100:
        score = 100.0
    return round(score, 2)


def rank_from_score(score: float) -> str:
    for thr, r in RANK_THRESHOLDS:
        if score >= thr:
            return r
    return "R"


def apply_rank(result: ScanResult) -> None:
    if result.error == "no_tls":
        result.score = 0.0
        result.rank = "R"
        return
    result.score = compute_score(result.findings)
    result.rank = rank_from_score(result.score)
