"""Unit tests for calendar view helpers."""
from __future__ import annotations

from datetime import date

import pytest

from events.bp.calendar.services.calendar_view import add_months, build_calendar_weeks


class TestAddMonths:
    def test_same_month(self):
        assert add_months(2025, 6, 0) == (2025, 6)

    def test_forward_one(self):
        assert add_months(2025, 6, 1) == (2025, 7)

    def test_december_to_january(self):
        assert add_months(2025, 12, 1) == (2026, 1)

    def test_january_to_december(self):
        assert add_months(2025, 1, -1) == (2024, 12)

    def test_multi_year_forward(self):
        assert add_months(2025, 1, 24) == (2027, 1)

    def test_multi_year_backward(self):
        assert add_months(2025, 3, -15) == (2023, 12)

    def test_negative_large(self):
        y, m = add_months(2025, 6, -30)
        assert m >= 1 and m <= 12
        assert y == 2022  # 2025-06 minus 30 months = 2022-12

    def test_forward_eleven(self):
        assert add_months(2025, 1, 11) == (2025, 12)

    def test_forward_twelve(self):
        assert add_months(2025, 1, 12) == (2026, 1)


class TestBuildCalendarWeeks:
    def test_returns_weeks(self):
        weeks = build_calendar_weeks(2025, 6)
        assert len(weeks) >= 4
        assert len(weeks) <= 6

    def test_seven_days_per_week(self):
        weeks = build_calendar_weeks(2025, 1)
        for week in weeks:
            assert len(week) == 7

    def test_day_structure(self):
        weeks = build_calendar_weeks(2025, 6)
        day = weeks[0][0]
        assert "date" in day
        assert "in_month" in day
        assert "is_today" in day
        assert isinstance(day["date"], date)

    def test_in_month_flag(self):
        weeks = build_calendar_weeks(2025, 6)
        # First day of first week might be in May
        june_days = [
            d for week in weeks for d in week if d["in_month"]
        ]
        assert len(june_days) == 30  # June has 30 days

    def test_february_leap_year(self):
        weeks = build_calendar_weeks(2024, 2)
        feb_days = [d for week in weeks for d in week if d["in_month"]]
        assert len(feb_days) == 29

    def test_february_non_leap(self):
        weeks = build_calendar_weeks(2025, 2)
        feb_days = [d for week in weeks for d in week if d["in_month"]]
        assert len(feb_days) == 28

    def test_starts_on_monday(self):
        weeks = build_calendar_weeks(2025, 6)
        # First day of first week should be a Monday
        assert weeks[0][0]["date"].weekday() == 0  # Monday
