"""Tests for AsyncWeatherClient (HTTP mocked with respx)."""

import pytest

httpx = pytest.importorskip("httpx")
respx = pytest.importorskip("respx")

from tests.conftest import (  # noqa: E402
    BASE,
    FAKE_TOKEN,
    load_fixture,
)

from accuweather_client import AsyncWeatherClient  # noqa: E402
from accuweather_client.exceptions import (  # noqa: E402
    RateLimitExceededError,
)


def mock_location(router):
    router.get(f"{BASE}/locations/v1/cities/search").respond(
        json=load_fixture("location_city.json")
    )


@respx.mock
async def test_async_current_conditions():
    mock_location(respx)
    respx.get(f"{BASE}/currentconditions/v1/22889").respond(
        json=load_fixture("current_conditions.json")
    )
    async with AsyncWeatherClient(token=FAKE_TOKEN, city="sydney") as client:
        conditions = await client.get_current_conditions()
    assert "sunny" in conditions.current_conditions


@respx.mock
async def test_async_5day_forecast_and_location_cache():
    mock_location(respx)
    route = respx.get(f"{BASE}/forecasts/v1/daily/5day/22889").respond(
        json=load_fixture("forecast_5day.json")
    )
    async with AsyncWeatherClient(token=FAKE_TOKEN, city="sydney") as client:
        forecast = await client.get_5day_forecast()
        await client.get_5day_forecast()
        assert (await client.get_location()).LocalizedName == "Sydney"
    assert forecast.text == "Pleasant this weekend"
    assert route.call_count == 2  # no cache_ttl -> both forecast calls hit


@respx.mock
async def test_async_rate_limit_error():
    respx.get(f"{BASE}/locations/v1/cities/search").respond(
        status_code=429, text="quota exceeded"
    )
    async with AsyncWeatherClient(token=FAKE_TOKEN, city="sydney") as client:
        with pytest.raises(RateLimitExceededError):
            await client.get_current_conditions()


def test_async_constructor_validates_arguments():
    with pytest.raises(ValueError, match="not both"):
        AsyncWeatherClient(token=FAKE_TOKEN, city="a", poi="b")
    with pytest.raises(ValueError):
        AsyncWeatherClient(token=FAKE_TOKEN)


@respx.mock
async def test_async_hourly_and_alerts():
    mock_location(respx)
    respx.get(f"{BASE}/forecasts/v1/hourly/12hour/22889").respond(
        json=load_fixture("hourly_12h.json")
    )
    respx.get(f"{BASE}/alerts/v1/22889").respond(
        json=load_fixture("alerts.json")
    )
    async with AsyncWeatherClient(token=FAKE_TOKEN, city="sydney") as client:
        hourly = await client.get_hourly_forecast_12h()
        alerts = await client.get_alerts()
    assert len(hourly.output) == 2
    assert alerts.count == 1
