"""Six-level nuanced vote evaluation.

Levels:
    0 - CONTRE
    1 - PAS DU TOUT
    2 - PAS D'ACCORD
    3 - NEUTRE
    4 - D'ACCORD
    5 - TOUT A FAIT

Adoption rule:
    The sum of votes at levels 3 + 4 + 5 must be >= threshold_pct% of total votes.
    A minimum number of participants is also required.
"""

from __future__ import annotations

LEVEL_LABELS: dict[int, str] = {
    0: "CONTRE",
    1: "PAS DU TOUT",
    2: "PAS D'ACCORD",
    3: "NEUTRE",
    4: "D'ACCORD",
    5: "TOUT A FAIT",
}

NUM_LEVELS = 6


def evaluate_nuanced(
    votes: list[int],
    threshold_pct: int = 80,
    min_participants: int = 59,
) -> dict:
    """Evaluate a nuanced vote from a list of individual vote levels.

    Parameters
    ----------
    votes:
        List of vote levels (each 0-5).  One entry per voter.
    threshold_pct:
        Minimum percentage of positive votes (levels 3-5) out of total
        for adoption.
    min_participants:
        Minimum number of participants required for validity.

    Returns
    -------
    dict
        {
            "total": int,
            "per_level_counts": {0: int, 1: int, ..., 5: int},
            "positive_count": int,       # levels 3 + 4 + 5
            "positive_pct": float,        # 0.0 - 100.0
            "threshold_met": bool,
            "min_participants_met": bool,
            "adopted": bool,
        }

    Raises
    ------
    ValueError
        If any vote value is outside the 0-5 range.
    """
    # Validate vote levels
    for v in votes:
        if v < 0 or v > 5:
            raise ValueError(
                f"Niveau de vote invalide : {v}. Les niveaux valides sont 0-5."
            )

    total = len(votes)

    per_level_counts: dict[int, int] = {level: 0 for level in range(NUM_LEVELS)}
    for v in votes:
        per_level_counts[v] += 1

    # Positive = levels 3 (NEUTRE), 4 (D'ACCORD), 5 (TOUT A FAIT)
    positive_count = per_level_counts[3] + per_level_counts[4] + per_level_counts[5]

    positive_pct = (positive_count / total * 100.0) if total > 0 else 0.0

    threshold_met = positive_pct >= threshold_pct
    min_participants_met = total >= min_participants
    adopted = threshold_met and min_participants_met

    return {
        "total": total,
        "per_level_counts": per_level_counts,
        "positive_count": positive_count,
        "positive_pct": round(positive_pct, 2),
        "threshold_met": threshold_met,
        "min_participants_met": min_participants_met,
        "adopted": adopted,
    }
