"""Tests for the pydantic response models and their conveniences."""

import pytest

from accuweather_client.icons import icon_to_description, icon_to_emoji
from accuweather_client.models import (
    CurrentConditionsModel,
    ForecastModel5Days,
    HourlyForecastModel,
    LocationModel,
)


def test_forecast_model_str_and_dict(forecast_payload):
    forecast = ForecastModel5Days.from_api_response(forecast_payload)
    assert "Pleasant this weekend" in str(forecast)
    assert forecast.to_dict()["Headline"]["Text"] == "Pleasant this weekend"
    assert forecast.daily_forecasts[0].day.emoji == "🌤️"


def test_forecast_tomorrow_falls_back_to_single_day(forecast_payload):
    forecast_payload["DailyForecasts"] = forecast_payload["DailyForecasts"][:1]
    forecast = ForecastModel5Days.from_api_response(forecast_payload)
    assert "Partly sunny" in forecast.forecast_tomorrow


def test_forecast_to_pandas_df(forecast_payload):
    pd = pytest.importorskip("pandas")
    forecast = ForecastModel5Days.from_api_response(forecast_payload)
    df = forecast.to_pandas_df()
    assert isinstance(df, pd.DataFrame)
    assert len(df) == 2
    assert "Temperature.Maximum.Value" in df.columns


def test_hourly_to_pandas_df(hourly_payload):
    pytest.importorskip("pandas")
    hourly = HourlyForecastModel(output=hourly_payload)
    df = hourly.to_pandas_df()
    assert len(df) == 2
    assert "Temperature.Value" in df.columns


def test_hourly_str_contains_emoji(hourly_payload):
    hourly = HourlyForecastModel(output=hourly_payload)
    assert "🌤️" in str(hourly)


def test_current_conditions_summary(conditions_payload):
    conditions = CurrentConditionsModel(output=conditions_payload)
    assert conditions.current_conditions == (
        "At the moment: sunny, with a temperature of 17.2C. "
        "The wind is coming from the WSW at 15.4km/h."
    )
    assert str(conditions) == conditions.current_conditions


def test_location_model_handles_list_and_single(
    location_payload, geoposition_payload
):
    as_list = LocationModel(response=location_payload)
    as_item = LocationModel(response=geoposition_payload)
    assert as_list.get_location_key() == "22889"
    assert as_item.get_location_key() == "324721"
    assert "Sydney" in str(as_list.first)


def test_models_tolerate_unknown_fields(conditions_payload):
    conditions_payload[0]["BrandNewApiField"] = {"nested": True}
    model = CurrentConditionsModel(output=conditions_payload)
    assert model.output[0]["BrandNewApiField"] == {"nested": True}


def test_icon_helpers():
    assert icon_to_description(1) == "Sunny"
    assert icon_to_emoji(1) == "☀️"
    assert icon_to_description(999) == "Unknown"
    assert icon_to_emoji(999) == "❔"


def test_token_validation_mixin_compat():
    from accuweather_client.exceptions import InvalidTokenError
    from accuweather_client.models import TokenValidation

    assert TokenValidation(token="b" * 32).token == "b" * 32
    with pytest.raises((InvalidTokenError, ValueError)):
        TokenValidation(token="nope")
