"""Недельная арифметика: границы недели, прогресс против ступени ВОЗ, вес."""

from datetime import date, timedelta

WEIGHT_WINDOW_DAYS = 7


def week_bounds(today):
    """Понедельник и воскресенье недели, в которую попадает день."""
    monday = today - timedelta(days=today.weekday())
    return monday, monday + timedelta(days=6)


def day_index(today):
    """Номер дня внутри недели, 1 — понедельник."""
    return today.weekday() + 1


def days_left(today):
    """Сколько дней недели осталось, включая сегодня."""
    return 7 - today.weekday()


def cardio_minutes(days, today):
    """Сумма exercise-минут за текущую неделю."""
    monday, sunday = week_bounds(today)
    return sum(
        row.exercise_min or 0
        for day, row in days.items()
        if monday <= day <= sunday
    )


def strength_days(workouts, today):
    """Число дней недели с силовой тренировкой (день, а не сессия)."""
    monday, sunday = week_bounds(today)
    return len({
        w.day for w in workouts
        if w.is_strength and monday <= w.day <= sunday
    })


def rolling_weight(days, today):
    """Среднее по замерам веса за последние 7 календарных дней."""
    window_start = today - timedelta(days=WEIGHT_WINDOW_DAYS - 1)
    weights = [
        row.weight
        for day, row in days.items()
        if window_start <= day <= today and row.weight is not None
    ]
    return round(sum(weights) / len(weights), 1) if weights else None


def last_weigh_in(days):
    """Последний замер веса: (дата, кг) или None."""
    measured = [(day, row.weight) for day, row in days.items() if row.weight is not None]
    return max(measured, key=lambda pair: pair[0]) if measured else None


MIN_WALK_MIN = 15
STRENGTH_URGENT_DAYS = 3


def suggestion(stage, cardio, strength, today):
    """Что сделать сегодня, чтобы неделя закрылась. Чистая арифметика, без Claude."""
    left = days_left(today)
    cardio_gap = max(0, stage["cardio_min"] - cardio)
    strength_gap = max(0, stage["strength_days"] - strength)

    if strength_gap and left <= STRENGTH_URGENT_DAYS:
        return "Силовая 35–45 мин — без неё неделя не закроется"

    if cardio_gap:
        per_day = -(-cardio_gap // left)
        minutes = max(MIN_WALK_MIN, -(-per_day // 5) * 5)
        if minutes >= cardio_gap:
            return f"Прогулка ~{minutes} мин — закроет неделю по кардио"
        return f"Прогулка ~{minutes} мин"

    if strength_gap:
        return "Силовая 35–45 мин"

    return "Неделя закрыта, сегодня по желанию"


def stage_for(stages, today):
    """Ступень ВОЗ, действующая на дату."""
    ordered = sorted(stages, key=lambda s: s["from"])
    current = ordered[0]
    for stage in ordered:
        if date.fromisoformat(stage["from"]) <= today:
            current = stage
    return current
