"""Tests for LocationClient (all HTTP mocked with `responses`)."""

import pytest
import responses
from tests.conftest import BASE

from accuweather_client import LocationClient
from accuweather_client.exceptions import LocationNotFoundError


@responses.activate
def test_search_city(token, location_payload):
    responses.get(f"{BASE}/locations/v1/cities/search", json=location_payload)
    result = LocationClient(token=token).search_city("sydney")
    assert result.first.Key == "22889"
    assert result.first.Country.EnglishName == "Australia"
    assert "sydney" in responses.calls[0].request.url.lower()


@responses.activate
def test_search_city_with_country_uses_general_search(token, location_payload):
    responses.get(f"{BASE}/locations/v1/search", json=location_payload)
    result = LocationClient(token=token).search_city(
        "sydney", country="canada"
    )
    assert result.get_location_key() == "22889"
    assert "sydney+canada" in responses.calls[0].request.url


@responses.activate
def test_search_poi_urlencodes_query(token, location_payload):
    responses.get(f"{BASE}/locations/v1/poi/search", json=location_payload)
    LocationClient(token=token).search_poi("Eiffel tower")
    assert "q=Eiffel+tower" in responses.calls[0].request.url


@responses.activate
def test_search_geoposition_single_item_response(token, geoposition_payload):
    responses.get(
        f"{BASE}/locations/v1/cities/geoposition/search",
        json=geoposition_payload,
    )
    result = LocationClient(token=token).search_geoposition(51.988, -4.88)
    # Single-item (non-list) responses must work too.
    assert result.get_location_key() == "324721"


def test_search_geoposition_validates_ranges(token):
    client = LocationClient(token=token)
    with pytest.raises(ValueError, match="Latitude"):
        client.search_geoposition(91, 0)
    with pytest.raises(ValueError, match="Longitude"):
        client.search_geoposition(0, 181)


@responses.activate
def test_empty_response_raises_location_not_found(token):
    responses.get(f"{BASE}/locations/v1/cities/search", json=[])
    with pytest.raises(LocationNotFoundError, match="atlantis"):
        LocationClient(token=token).search_city("atlantis")


@responses.activate
def test_autocomplete(token, location_payload):
    responses.get(
        f"{BASE}/locations/v1/cities/autocomplete", json=location_payload
    )
    suggestions = LocationClient(token=token).autocomplete("syd")
    assert suggestions[0].LocalizedName == "Sydney"


@responses.activate
def test_search_postal_code_with_country(token, location_payload):
    responses.get(
        f"{BASE}/locations/v1/postalcodes/NL/search", json=location_payload
    )
    result = LocationClient(token=token).search_postal_code(
        "1012", country="NL"
    )
    assert result.first.Key == "22889"


@responses.activate
def test_search_ip(token, geoposition_payload):
    responses.get(
        f"{BASE}/locations/v1/cities/ipaddress", json=geoposition_payload
    )
    result = LocationClient(token=token).search_ip("203.0.113.7")
    assert result.first.Key == "324721"


def test_resolve_rejects_conflicting_input(token):
    client = LocationClient(token=token)
    with pytest.raises(ValueError, match="not both"):
        client.resolve(city="sydney", poi="Opera House")
    with pytest.raises(ValueError, match="both"):
        client.resolve(lat=1.0)
    with pytest.raises(ValueError):
        client.resolve()


@responses.activate
def test_deprecated_get_location_model_still_works(token, location_payload):
    responses.get(f"{BASE}/locations/v1/cities/search", json=location_payload)
    from accuweather_client.clients import get_location_model

    with pytest.warns(DeprecationWarning):
        result = get_location_model(city="sydney", token=token)
    assert result.location.get_location_key() == "22889"


@responses.activate
def test_autocomplete_slim_payload(token):
    # Autocomplete returns trimmed objects: no EnglishName inside Country.
    responses.get(
        f"{BASE}/locations/v1/cities/autocomplete",
        json=[
            {
                "Version": 1,
                "Key": "22889",
                "Type": "City",
                "Rank": 21,
                "LocalizedName": "Sydney",
                "Country": {"ID": "AU", "LocalizedName": "Australia"},
                "AdministrativeArea": {
                    "ID": "NSW",
                    "LocalizedName": "New South Wales",
                },
            }
        ],
    )
    (suggestion,) = LocationClient(token=token).autocomplete("syd")
    assert suggestion.Country.name == "Australia"
    assert "Sydney, Australia" in str(suggestion)


@responses.activate
def test_http_403_mentions_plan_tier(token):
    responses.get(
        f"{BASE}/locations/v1/cities/search", body="denied", status=403
    )
    from accuweather_client.exceptions import ApiRequestError

    with pytest.raises(ApiRequestError, match="AccuWeather plan"):
        LocationClient(token=token).search_city("sydney")
