"""채점 서비스 — 결과 입력 시 해당 경기 유저 픽 전수 채점 + 유저별 누적.

관리자 setResult 와 워커가 공용으로 사용. scoring.grade_prediction 적용
(scoring.json 배점) 후 services.points 로 user_points 누적 갱신.
"""
from __future__ import annotations

import logging

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from ..domain import now_utc
from ..models import Match, UserPrediction
from ..scoring import grade_prediction, outcome_of
from .points import accumulate_user_points

log = logging.getLogger("triplepick.grading")


async def apply_result(db: AsyncSession, match: Match, score_a: int, score_b: int) -> int:
    """결과 기록 + 해당 경기 픽 전수 채점 + 유저별 포인트 누적. 채점된 픽 수 반환."""
    match.result_score_a = score_a
    match.result_score_b = score_b
    match.result_outcome = outcome_of(score_a, score_b)
    match.status = "finished"
    match.finished_at = now_utc()

    picks = (
        await db.execute(
            select(UserPrediction).where(UserPrediction.match_id == match.match_id)
        )
    ).scalars().all()

    for p in picks:
        key, value = grade_prediction(p.score_a, p.score_b, score_a, score_b)
        p.points = value
        p.scored_at = now_utc()

    # 채점된 픽의 유저(이메일)별 누적 포인트 갱신 — 같은 트랜잭션
    await accumulate_user_points(db, {p.email for p in picks})

    await db.commit()
    log.info("graded %d picks for %s (%d-%d)", len(picks), match.match_id, score_a, score_b)
    return len(picks)
