"""Model utilities."""
from functools import wraps

from pydantic import computed_field

from epeira.helpers.parsing import get_override_name


def extended_computed_field(
    _func=None,
    *,
    subcategory: str | None = None,
    units: str | None = None,
    **cf_kwargs,
):
    """Return a modified computed field with supplemental features for modeling."""
    def decorator(func):
        field_name = func.__name__
        override_name = get_override_name(field_name)

        @wraps(func)
        def wrapper(self):
            override_value = getattr(self, override_name, None)
            if override_value is not None:
                return override_value
            return func(self)

        # Attach metadata
        wrapper.__model_subcategory__ = subcategory
        wrapper.__model_units__ = units
        wrapper.__override_field_name__ = override_name

        descriptor = computed_field(**cf_kwargs)(wrapper)

        # Attach metadata to descriptor too (optional but useful)
        descriptor.__model_subcategory__ = subcategory
        descriptor.__model_units__ = units
        descriptor.__override_field_name__ = override_name

        return descriptor

    # If used as @model_computed_field
    if _func is not None:
        return decorator(_func)

    return decorator
