"""Semaines ISO 8601, dates françaises, règles de saisie (tests unitaires)."""
from datetime import date, datetime

import pytest

from edcf.core import isoweek
from edcf.services.bilans import parse_count


def test_semaine_40_2026():
    start, end = isoweek.week_bounds(2026, 40)
    assert start == date(2026, 9, 28) and start.weekday() == 0
    assert end == date(2026, 10, 4) and end.weekday() == 6
    assert isoweek.week_label(2026, 40) == "Semaine 40 — du 28/09/2026 au 04/10/2026"


def test_jours_de_la_semaine_40_appartiennent_a_la_semaine_40():
    for day in range(28, 31):
        assert isoweek.week_of(date(2026, 9, day)) == (2026, 40)
    for day in range(1, 5):
        assert isoweek.week_of(date(2026, 10, day)) == (2026, 40)
    assert isoweek.week_of(date(2026, 10, 5)) == (2026, 41)


def test_annees_a_53_semaines_et_changement_d_annee():
    assert isoweek.weeks_in_year(2026) == 53
    assert isoweek.weeks_in_year(2027) == 52
    assert isoweek.week_bounds(2026, 53) == (date(2026, 12, 28), date(2027, 1, 3))
    assert isoweek.week_of(date(2027, 1, 1)) == (2026, 53)
    assert isoweek.shift_week(2026, 53, 1) == (2027, 1)
    with pytest.raises(ValueError):
        isoweek.week_bounds(2027, 53)


def test_dates_francaises_et_fuseau_paris():
    assert isoweek.fr_date(date(2026, 10, 4)) == "04/10/2026"
    assert isoweek.fr_long_date(date(2026, 9, 28)) == "lundi 28 septembre 2026"
    from zoneinfo import ZoneInfo
    utc = datetime(2026, 10, 4, 22, 30, tzinfo=ZoneInfo("UTC"))  # lundi 00:30 à Paris
    assert isoweek.current_week(utc) == (2026, 41)
    assert isoweek.fr_datetime(utc) == "05/10/2026 à 00:30"


def test_jeudi_iso_rattache_s40_a_octobre():
    assert isoweek.week_thursday(2026, 40) == date(2026, 10, 1)


@pytest.mark.parametrize("raw,expected", [
    ("", (None, None)), (None, (None, None)), ("  ", (None, None)),
    ("0", (0, None)), (0, (0, None)), ("12", (12, None)), (" 7 ", (7, None)), (3.0, (3, None)),
])
def test_vide_different_de_zero(raw, expected):
    assert parse_count(raw) == expected


@pytest.mark.parametrize("raw", ["-1", -3, "2,5", "2.5", 2.5, "abc", "1e3", "100001"])
def test_valeurs_refusees(raw):
    value, error = parse_count(raw)
    assert value is None and error
