"""app.weather_render -- pure-logic drawing helpers, no HTTP/DB.
Mirrors calendar_render.py's own testing posture (this module has no
dedicated test file there either, since it's exercised indirectly via
test_widgets_calendar.py) but covers the non-obvious behavior worth
pinning down directly: build_multi_city's label shortening, and that
weather icons actually use the panel's ink colors (not flat black --
caught via browser verification that a monochrome sun read as an
unrecognizable crosshair glyph, not a sun)."""

from __future__ import annotations

from PIL import Image, ImageDraw

from app import weather_render
from app.image_pipeline import DEFAULT_PALETTE_RGB


def test_build_multi_city_shortens_full_geocoder_labels_for_display(monkeypatch):
    """Cached entries carry the full disambiguated geocoder label (e.g.
    "Seattle, Washington, United States" -- see get_or_refresh_weather_
    widget_data/weather.geocode_city). Drawing the whole thing made a
    single city's row overflow past the widget's own width in practice
    (caught via browser verification) -- only the city name should reach
    draw_weather_row, same shortening calendar_render.py's
    _weather_for_day already does for its own embedded strip."""
    seen_labels = []
    real_draw_weather_row = weather_render.draw_weather_row

    def spy(img, draw, x0, y0, max_w, entries, icon_r, font, units, show_labels=True, palette_rgb=None):
        seen_labels.extend(e["label"] for e in entries)
        return real_draw_weather_row(img, draw, x0, y0, max_w, entries, icon_r, font, units, show_labels,
                                     palette_rgb)

    monkeypatch.setattr(weather_render, "draw_weather_row", spy)

    cities = [
        {"label": "Seattle, Washington, United States", "high": 65, "low": 50, "category": "rain"},
        {"label": "Portland, Oregon, United States", "high": 75, "low": 55, "category": "clear"},
    ]
    img = weather_render.build_multi_city(cities, 400, 150)
    assert img.size == (400, 150)
    assert seen_labels == ["Seattle", "Portland"]


def test_build_multi_city_empty_list_returns_blank_canvas():
    img = weather_render.build_multi_city([], 400, 150)
    assert img.size == (400, 150)


def _colors_present(img: Image.Image) -> set[tuple[int, int, int]]:
    return {c for _, c in img.getcolors(maxcolors=100_000)}


def test_draw_weather_icon_clear_uses_panel_yellow_not_flat_black():
    img = Image.new("RGB", (100, 100), (255, 255, 255))
    draw = ImageDraw.Draw(img)
    weather_render.draw_weather_icon(draw, 50, 50, 30, "clear")
    colors = _colors_present(img)
    assert tuple(DEFAULT_PALETTE_RGB[2]) in colors  # yellow
    assert (0, 0, 0) not in colors  # no flat-black sun


def test_draw_weather_icon_rain_uses_panel_blue():
    img = Image.new("RGB", (100, 100), (255, 255, 255))
    draw = ImageDraw.Draw(img)
    weather_render.draw_weather_icon(draw, 50, 50, 30, "rain")
    assert tuple(DEFAULT_PALETTE_RGB[4]) in _colors_present(img)  # blue raindrops


def test_draw_weather_icon_thunderstorm_uses_panel_yellow():
    img = Image.new("RGB", (100, 100), (255, 255, 255))
    draw = ImageDraw.Draw(img)
    weather_render.draw_weather_icon(draw, 50, 50, 30, "thunderstorm")
    assert tuple(DEFAULT_PALETTE_RGB[2]) in _colors_present(img)  # yellow bolt


def test_draw_weather_icon_respects_a_custom_frame_palette():
    """A frame with an Advanced-configuration palette override (see
    Frame.palette_rgb) should still get ITS actual yellow, not the
    hardcoded default -- same resolution rule as calendar_render.py's
    _event_colors."""
    custom_palette = [(0, 0, 0), (255, 255, 255), (10, 20, 30), (0, 0, 0), (0, 0, 0), (0, 0, 0)]
    img = Image.new("RGB", (100, 100), (255, 255, 255))
    draw = ImageDraw.Draw(img)
    weather_render.draw_weather_icon(draw, 50, 50, 30, "clear", palette_rgb=custom_palette)
    assert (10, 20, 30) in _colors_present(img)
