from __future__ import annotations

from io import BytesIO

from PIL import Image

from src.main import _inject_og_tags
from src.og_service import OGImageService, aggregate_for_og, format_date_fr, format_og_date_range


def test_aggregate_for_og_basic() -> None:
    data = [
        {"temp_min": 4.2, "temp_max": 12.3, "description": "Couvert", "icon": "☁️"},
        {"temp_min": 1.5, "temp_max": 14.8, "description": "Couvert", "icon": "☁️"},
        {"temp_min": 3.1, "temp_max": 10.0, "description": "Pluie", "icon": "🌧️"},
    ]

    result = aggregate_for_og(data)

    assert result == {
        "temp_min": 1.5,
        "temp_max": 14.8,
        "dominant_desc": "Couvert",
        "dominant_icon": "☁️",
    }


def test_aggregate_for_og_empty() -> None:
    assert aggregate_for_og([]) == {
        "temp_min": None,
        "temp_max": None,
        "dominant_desc": None,
        "dominant_icon": None,
    }


def test_aggregate_for_og_partial_data() -> None:
    data = [
        {"temp_min": None, "temp_max": 13.0, "description": "Dégagé"},
        {"temp_min": 2.0, "temp_max": None, "description": "Dégagé"},
        {"temp_min": 1.0, "temp_max": 11.0, "description": "Brume", "icon": "🌫️"},
    ]

    result = aggregate_for_og(data)

    assert result["temp_min"] == 1.0
    assert result["temp_max"] == 13.0
    assert result["dominant_desc"] == "Dégagé"
    assert result["dominant_icon"] is None


def test_format_date_fr_basic() -> None:
    assert format_date_fr("2026-03-12") == "12 mars 2026"


def test_format_date_fr_first_of_month() -> None:
    assert format_date_fr("2026-01-01") == "1er janvier 2026"


def test_format_og_date_range_single_day() -> None:
    assert format_og_date_range("2026-03-12", "2026-03-12") == "le 12 mars 2026"


def test_format_og_date_range_same_month() -> None:
    assert format_og_date_range("2026-03-09", "2026-03-11") == "du 9 au 11 mars 2026"


def test_format_og_date_range_cross_month() -> None:
    assert (
        format_og_date_range("2026-02-28", "2026-03-03")
        == "du 28 février au 3 mars 2026"
    )


def test_format_og_date_range_cross_year() -> None:
    assert (
        format_og_date_range("2025-12-28", "2026-01-03")
        == "du 28 décembre 2025 au 3 janvier 2026"
    )


def test_aggregate_for_og_returns_dominant_icon() -> None:
    data = [
        {
            "temp_min": 1.5,
            "temp_max": 8.0,
            "description": "Ciel dégagé",
            "icon": "☀️",
        },
        {
            "temp_min": 2.0,
            "temp_max": 9.0,
            "description": "Ciel dégagé",
            "icon": "☀️",
        },
    ]

    result = aggregate_for_og(data)

    assert result["dominant_icon"] == "☀️"


def test_og_image_generate_returns_png() -> None:
    service = OGImageService()

    image_bytes = service.generate(
        "Bordeaux",
        "2026-03-09",
        "2026-03-11",
        3.2,
        14.6,
        "Couvert",
        "☀️",
    )

    assert image_bytes.startswith(b"\x89PNG")


def test_og_image_generate_dimensions() -> None:
    service = OGImageService()

    image_bytes = service.generate(
        "Bordeaux",
        "2026-03-09",
        "2026-03-11",
        3.2,
        14.6,
        "Couvert",
        "☀️",
    )
    image = Image.open(BytesIO(image_bytes))

    assert image.size == (1200, 630)


def test_og_image_generate_without_weather_data() -> None:
    service = OGImageService()

    image_bytes = service.generate(
        "Bordeaux",
        "2026-03-09",
        "2026-03-11",
        None,
        None,
        None,
        None,
    )

    assert image_bytes.startswith(b"\x89PNG")


def test_og_image_cache() -> None:
    service = OGImageService()

    first = service.generate(
        "Bordeaux",
        "2026-03-09",
        "2026-03-11",
        3.2,
        14.6,
        "Couvert",
        "☀️",
    )
    second = service.generate(
        "Bordeaux",
        "2026-03-09",
        "2026-03-11",
        3.2,
        14.6,
        "Couvert",
        "☀️",
    )

    assert first is second


def test_og_image_generate_with_weather_icon() -> None:
    service = OGImageService()

    image_bytes = service.generate(
        "Bordeaux",
        "2026-03-09",
        "2026-03-11",
        3.2,
        14.6,
        "Ciel dégagé",
        "☀️",
    )
    image = Image.open(BytesIO(image_bytes))

    assert image.size == (1200, 630)
    assert image_bytes.startswith(b"\x89PNG")


def test_inject_og_tags_escapes_html() -> None:
    template = '<meta property="og:title" content="A" />'

    html = _inject_og_tags(template, {"og:title": '<script>alert("x")</script>'})

    assert "&lt;script&gt;alert(&quot;x&quot;)&lt;/script&gt;" in html
    assert "<script>" not in html
