"""
구매 이력 관리 + 결과 체크 모듈.

- check_purchases_for_draw(): 특정 회차 구매 건들의 결과를 자동 체크
- 체커의 _calc_rank 재사용
- 결과 체크 후 strategy_performance 자동 갱신
"""
import logging
from .db import (
    get_draw, get_purchases, update_purchase_results,
    upsert_strategy_performance,
)
from .checker import _calc_rank

logger = logging.getLogger("lotto-backend")

RANK_PRIZE = {1: 0, 2: 0, 3: 1_500_000, 4: 50_000, 5: 5_000}


def check_purchases_for_draw(drw_no: int) -> int:
    """
    특정 회차 결과로 해당 회차 구매 건들을 채점한다.
    Returns: 채점한 구매 건 수
    """
    win_row = get_draw(drw_no)
    if not win_row:
        return 0

    win_nums = [win_row["n1"], win_row["n2"], win_row["n3"],
                win_row["n4"], win_row["n5"], win_row["n6"]]
    bonus = win_row["bonus"]

    unchecked = get_purchases(draw_no=drw_no, checked=False)

    strategy_agg = {}

    count = 0
    for purchase in unchecked:
        numbers_list = purchase["numbers"]
        if not numbers_list:
            continue

        results = []
        for nums in numbers_list:
            rank, correct, has_bonus = _calc_rank(nums, win_nums, bonus)
            prize = RANK_PRIZE.get(rank, 0)
            results.append({
                "numbers": nums,
                "rank": rank,
                "correct": correct,
                "has_bonus": has_bonus,
                "prize": prize,
            })

        total_prize = sum(r["prize"] for r in results)
        update_purchase_results(purchase["id"], results, total_prize)

        strat = purchase["source_strategy"]
        if strat not in strategy_agg:
            strategy_agg[strat] = {
                "sets_count": 0,
                "total_correct": 0,
                "max_correct": 0,
                "prize_total": 0,
                "scores": [],
                "_results": [],
            }
        agg = strategy_agg[strat]
        agg["_results"].extend(results)
        for r in results:
            agg["sets_count"] += 1
            agg["total_correct"] += r["correct"]
            agg["max_correct"] = max(agg["max_correct"], r["correct"])
            agg["prize_total"] += r["prize"]
            agg["scores"].append(r["correct"] / 6.0)

        count += 1

    for strat, agg in strategy_agg.items():
        avg_score = sum(agg["scores"]) / len(agg["scores"]) if agg["scores"] else 0.0
        upsert_strategy_performance(
            strategy=strat,
            draw_no=drw_no,
            sets_count=agg["sets_count"],
            total_correct=agg["total_correct"],
            max_correct=agg["max_correct"],
            prize_total=agg["prize_total"],
            avg_score=round(avg_score, 4),
        )

        # EMA 피드백 루프: 전략 가중치 진화
        try:
            from .strategy_evolver import evolve_after_check
            evolve_after_check(strat, drw_no, agg["_results"])
        except Exception:
            logger.debug(f"[purchase_manager] evolve_after_check 건너뜀: {strat}")

    logger.info(f"[purchase_manager] {drw_no}회차 구매 {count}건 체크 완료")
    return count


def get_recent_performance(limit: int = 3) -> list:
    """최근 N회차 내 구매 성과 요약. 없으면 빈 리스트."""
    from . import db
    purchases = db.get_purchases() or []
    by_draw: dict = {}
    for p in purchases:
        d = p.get("draw_no")
        if not d:
            continue
        results = p.get("results") or []
        max_correct = max((int(r.get("correct") or 0) for r in results), default=0)
        slot = by_draw.setdefault(d, {"draw_no": d, "purchased_sets": 0, "best_match": 0})
        slot["purchased_sets"] += int(p.get("sets") or 1)
        slot["best_match"] = max(slot["best_match"], max_correct)
    return sorted(by_draw.values(), key=lambda x: -x["draw_no"])[:limit]
