# apps/participants/services.py
from django.db import transaction
from .models import Participant
from apps.settingsapp.models import GradingSettings

def _factor(diff: float) -> float:
    if diff <= 10:
        return 1.0
    elif diff <= 20:
        return 0.8
    return 0.6

def calculate_scores():
    """Recalcula y persiste 'score' para todos los participantes"""
    settings = GradingSettings.get()
    participants = list(Participant.objects.all())

    # 1) Base Entregable + Presentación
    for p in participants:
        p.score = settings.report_weight + settings.presentation_weight

        # 2) Similitud
        for diff, weight in [
            (p.R_diff,  settings.R_weight),
            (p.L_diff,  settings.L_weight),
            (p.Ph_diff, settings.Ph_weight),
            (p.Pcu_diff,settings.Pcu_weight),
        ]:
            p.score += _factor(diff) * weight

    # 3) Objetivo (rank por métrica)
    sorted_by_obj = sorted(participants, key=lambda x: x.s_vol_over_eta)
    for idx, p in enumerate(sorted_by_obj, start=1):
        p.score += max(settings.objective_weight - (idx - 1), 0)

    # 4) Persistimos en batch
    with transaction.atomic():
        for p in participants:
            p.save(update_fields=["score"])
