import datetime as dt

from pydantic import BaseModel

from fbnconfig.coretypes import IsoDateTime


class DateModel(BaseModel):
    """Minimal model for testing IsoDateTime serialization/deserialization."""
    value: IsoDateTime


class DescribeIsoDateTime:
    """Tests for IsoDateTime (des_isodate + ser_isodate) through model validation and serialization."""

    def test_validate_plain_date(self):
        model = DateModel.model_validate({"value": dt.date(2024, 6, 15)})
        assert model.value == dt.date(2024, 6, 15)
        assert type(model.value) is dt.date

    def test_validate_datetime_normalized_to_utc(self):
        value = dt.datetime(2024, 6, 15, 10, 30, 0, tzinfo=dt.timezone(dt.timedelta(hours=5)))
        model = DateModel.model_validate({"value": value})
        assert model.value == dt.datetime(2024, 6, 15, 5, 30, 0, tzinfo=dt.timezone.utc)

    def test_validate_iso_string_with_timezone(self):
        model = DateModel.model_validate({"value": "2024-06-15T10:30:00+00:00"})
        assert model.value == dt.datetime(2024, 6, 15, 10, 30, 0, tzinfo=dt.timezone.utc)

    def test_validate_iso_string_without_timezone(self):
        model = DateModel.model_validate({"value": "2024-06-15T10:30:00"})
        assert model.value == dt.datetime(2024, 6, 15, 10, 30, 0)

    def test_validate_date_only_string(self):
        model = DateModel.model_validate({"value": "2024-06-15"})
        assert isinstance(model.value, dt.date)
        assert model.value.year == 2024
        assert model.value.month == 6
        assert model.value.day == 15

    def test_serialize_utc_datetime(self):
        model = DateModel.model_validate({"value": "2024-06-15T10:30:00+00:00"})
        result = model.model_dump(mode="json")
        assert result == {"value": "2024-06-15T10:30:00+00:00"}

    def test_serialize_date(self):
        model = DateModel.model_validate({"value": dt.date(2024, 6, 15)})
        result = model.model_dump(mode="json")
        assert result == {"value": "2024-06-15"}
