from enum import StrEnum, auto
from typing import ClassVar

import pytest
from astropydantic import AstroPydanticTime, AstroPydanticUnit

from ctao_datamodel import AstroField, ModelBase, doc


class OptionEnum(StrEnum):
    """Test of an enum."""

    ONE = auto()
    TWO = auto()
    THREE = auto()


class Pointing(ModelBase):
    """Describes the spatial direction of the observation, relative to the
    center of the subarray FOV, used to find observations.
    """

    _namespace: ClassVar = "Test.Namespace"

    ra: float = AstroField(
        description="ICRS Right ascension of the FOV center at `t_start`",
        unit="deg",
        fits_keyword="RA_PNT",
        ivoa_keyword="s_ra",
        ucd="pos.eq.ra",
    )

    dec: float = AstroField(
        description="ICRS Declination of the FOV center at `t_start`.",
        unit="deg",
        fits_keyword="DEC_PNT",
        ivoa_keyword="s_dec",
        ucd="pos.eq.dec",
    )

    time: AstroPydanticTime
    unit: AstroPydanticUnit


class ParentModel(ModelBase):
    """Example model that has inheritance"""

    x: float


class ChildModel(ParentModel):
    y: float = AstroField(description="Y value", unit="m")


class ExampleModel(ModelBase):
    """Common metadata that should be specified for all data products,
    regardless of their type or origin. It forms the basis of a file catalog.
    """

    reference_version: str = AstroField(
        description="reference version",
        default="2.0",
    )
    license: str = AstroField(
        description="License for this data product",
        default="CC-BY-SA",
        fits_keyword="LICENSE",
        examples=["CC-BY-SA"],
    )
    optional_option: OptionEnum | None = AstroField(default=None)
    pointing: Pointing = AstroField(description=doc(Pointing))
    child: ChildModel


@pytest.fixture(scope="session")
def example_model() -> type[ModelBase]:
    return ExampleModel


@pytest.fixture()
def example_model_instance() -> ExampleModel:
    return ExampleModel(
        pointing=Pointing(
            ra=198.2,
            dec=-20.1,
            time="2025-10-15T12:14:23.323",
            unit="deg",
        ),
        child=ChildModel(x=3.0, y=6.0),
    )
