"""Tests for user-timezone helpers (services/tz.py)."""

from datetime import datetime
from unittest.mock import AsyncMock, patch
from zoneinfo import ZoneInfo

import pytest


@pytest.mark.asyncio
async def test_get_user_tz_returns_configured_zone():
    from scribe.services import tz as tz_mod

    with patch.object(tz_mod, "get_setting", AsyncMock(return_value="America/New_York")):
        zone = await tz_mod.get_user_tz(1)
    assert zone == ZoneInfo("America/New_York")


@pytest.mark.asyncio
async def test_get_user_tz_falls_back_to_utc_on_bad_input():
    from scribe.services import tz as tz_mod

    with patch.object(tz_mod, "get_setting", AsyncMock(return_value="Not/AZone")):
        zone = await tz_mod.get_user_tz(1)
    assert zone == ZoneInfo("UTC")


@pytest.mark.asyncio
async def test_user_day_date_before_4am_returns_yesterday():
    """00:00–03:59 local still shows yesterday's day_date."""
    from scribe.services import tz as tz_mod

    ny = ZoneInfo("America/New_York")
    # 02:00 NY on 2026-04-13 → day_date = 2026-04-12 (still pre-rollover)
    fake_now = datetime(2026, 4, 13, 2, 0, tzinfo=ny)

    class _FakeDatetime(datetime):
        @classmethod
        def now(cls, tz=None):
            return fake_now

    with patch.object(tz_mod, "get_user_tz", AsyncMock(return_value=ny)), \
         patch.object(tz_mod, "datetime", _FakeDatetime):
        day = await tz_mod.user_day_date(1)
    assert day.isoformat() == "2026-04-12"


@pytest.mark.asyncio
async def test_user_day_date_after_4am_returns_today():
    from scribe.services import tz as tz_mod

    ny = ZoneInfo("America/New_York")
    fake_now = datetime(2026, 4, 13, 4, 30, tzinfo=ny)

    class _FakeDatetime(datetime):
        @classmethod
        def now(cls, tz=None):
            return fake_now

    with patch.object(tz_mod, "get_user_tz", AsyncMock(return_value=ny)), \
         patch.object(tz_mod, "datetime", _FakeDatetime):
        day = await tz_mod.user_day_date(1)
    assert day.isoformat() == "2026-04-13"
