import random
from typing import List, Dict, Any, Tuple


def weighted_sample_6(weights: Dict[int, float]) -> List[int]:
    """
    가중 확률 샘플링으로 중복 없이 6개 번호 추출.
    weights: {1: w1, 2: w2, ..., 45: w45}
    """
    pool = list(range(1, 46))
    chosen: List[int] = []
    for _ in range(6):
        total = sum(weights[n] for n in pool)
        r = random.random() * total
        acc = 0.0
        for n in pool:
            acc += weights[n]
            if acc >= r:
                chosen.append(n)
                pool.remove(n)
                break
    return chosen

def calc_metrics(numbers: List[int]) -> Dict[str, Any]:
    nums = sorted(numbers)
    s = sum(nums)
    odd = sum(1 for x in nums if x % 2 == 1)
    even = len(nums) - odd
    mn, mx = nums[0], nums[-1]
    rng = mx - mn

    # 1-10, 11-20, 21-30, 31-40, 41-45
    buckets = {
        "1-10": 0,
        "11-20": 0,
        "21-30": 0,
        "31-40": 0,
        "41-45": 0,
    }
    for x in nums:
        if 1 <= x <= 10:
            buckets["1-10"] += 1
        elif 11 <= x <= 20:
            buckets["11-20"] += 1
        elif 21 <= x <= 30:
            buckets["21-30"] += 1
        elif 31 <= x <= 40:
            buckets["31-40"] += 1
        else:
            buckets["41-45"] += 1

    return {
        "sum": s,
        "odd": odd,
        "even": even,
        "min": mn,
        "max": mx,
        "range": rng,
        "buckets": buckets,
    }

def calc_recent_overlap(numbers: List[int], draws: List[Tuple[int, List[int]]], last_k: int) -> Dict[str, Any]:
    """
    draws: [(drw_no, [n1..n6]), ...] 오름차순
    last_k: 최근 k회 기준 중복
    """
    if last_k <= 0:
        return {"last_k": 0, "repeats": 0, "repeated_numbers": []}

    recent = draws[-last_k:] if len(draws) >= last_k else draws
    recent_set = set()
    for _, nums in recent:
        recent_set.update(nums)

    repeated = sorted(set(numbers) & recent_set)
    return {
        "last_k": len(recent),
        "repeats": len(repeated),
        "repeated_numbers": repeated,
    }
