"""Unit tests for personal calendar ICS generation."""

from types import SimpleNamespace

from icalendar import Calendar as ICalendar

from duty_teller.api.personal_calendar_ics import build_personal_ics, build_team_ics


# Minimal Duty-like object for build_personal_ics(duties_with_name: list[tuple[Duty, str]])
def _duty(id_, start_at, end_at, event_type="duty"):
    return (
        SimpleNamespace(
            id=id_, start_at=start_at, end_at=end_at, event_type=event_type
        ),
        "Test User",
    )


def test_build_personal_ics_empty_returns_valid_calendar():
    """Empty list produces VCALENDAR with no VEVENTs."""
    ics = build_personal_ics([])
    assert ics.startswith(b"BEGIN:VCALENDAR")
    assert ics.rstrip().endswith(b"END:VCALENDAR")
    cal = ICalendar.from_ical(ics)
    assert cal is not None
    events = [c for c in cal.walk() if c.name == "VEVENT"]
    assert len(events) == 0


def test_build_personal_ics_one_duty():
    """One duty produces one VEVENT with correct DTSTART/DTEND/SUMMARY."""
    duties = [
        _duty(1, "2025-02-20T09:00:00Z", "2025-02-20T18:00:00Z", "duty"),
    ]
    ics = build_personal_ics(duties)
    cal = ICalendar.from_ical(ics)
    assert cal is not None
    events = [c for c in cal.walk() if c.name == "VEVENT"]
    assert len(events) == 1
    ev = events[0]
    assert ev.get("summary") == "Duty"
    assert "2025-02-20" in str(ev.get("dtstart").dt)
    assert "2025-02-20" in str(ev.get("dtend").dt)
    assert b"duty-1@duty-teller" in ics or "duty-1@duty-teller" in ics.decode("utf-8")


def test_build_team_ics_vevent_has_description_with_full_name():
    """Team ICS VEVENT has SUMMARY=full_name and DESCRIPTION=full_name."""
    duties = [
        _duty(1, "2025-02-20T09:00:00Z", "2025-02-20T18:00:00Z", "duty"),
    ]
    ics = build_team_ics(duties)
    cal = ICalendar.from_ical(ics)
    assert cal is not None
    events = [c for c in cal.walk() if c.name == "VEVENT"]
    assert len(events) == 1
    ev = events[0]
    assert ev.get("summary") == "Test User"
    assert ev.get("description") == "Test User"
    assert b"Team Calendar" in ics or "Team Calendar" in ics.decode("utf-8")


def test_build_team_ics_empty_full_name_summary_fallback():
    """When full_name is empty or missing, SUMMARY is 'Duty'."""
    duty_ns = SimpleNamespace(
        id=1,
        start_at="2025-02-20T09:00:00Z",
        end_at="2025-02-20T18:00:00Z",
        event_type="duty",
    )
    for empty_name in ("", "   ", None):
        duties = [(duty_ns, empty_name)]
        ics = build_team_ics(duties)
        cal = ICalendar.from_ical(ics)
        events = [c for c in cal.walk() if c.name == "VEVENT"]
        assert len(events) == 1
        assert events[0].get("summary") == "Duty"


def test_build_personal_ics_event_types():
    """Unavailable and vacation get correct SUMMARY."""
    duties = [
        _duty(1, "2025-02-20T09:00:00Z", "2025-02-21T09:00:00Z", "unavailable"),
        _duty(2, "2025-02-25T00:00:00Z", "2025-03-01T00:00:00Z", "vacation"),
    ]
    ics = build_personal_ics(duties)
    cal = ICalendar.from_ical(ics)
    events = [c for c in cal.walk() if c.name == "VEVENT"]
    assert len(events) == 2
    summaries = [str(ev.get("summary")) for ev in events]
    assert "Unavailable" in summaries
    assert "Vacation" in summaries


def test_build_personal_ics_naive_datetime_treated_as_utc():
    """Duties with start_at/end_at without Z (naive datetime) are treated as UTC."""
    duties = [
        _duty(1, "2025-02-20T09:00:00", "2025-02-20T18:00:00", "duty"),
    ]
    ics = build_personal_ics(duties)
    cal = ICalendar.from_ical(ics)
    assert cal is not None
    events = [c for c in cal.walk() if c.name == "VEVENT"]
    assert len(events) == 1
    ev = events[0]
    assert ev.get("summary") == "Duty"
    assert "2025-02-20" in str(ev.get("dtstart").dt)
    assert "2025-02-20" in str(ev.get("dtend").dt)
