"""Declarative base and shared column helpers."""

import enum
import uuid
from datetime import datetime

from sqlalchemy import DateTime, Enum, Uuid, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column


class Base(DeclarativeBase):
    pass


def uuid_pk() -> Mapped[uuid.UUID]:
    return mapped_column(Uuid, primary_key=True, default=uuid.uuid4)


def created_at_col() -> Mapped[datetime]:
    return mapped_column(DateTime(timezone=True), server_default=func.now(), nullable=False)


def updated_at_col() -> Mapped[datetime]:
    return mapped_column(
        DateTime(timezone=True),
        server_default=func.now(),
        onupdate=func.now(),
        nullable=False,
    )


TimestampTZ = DateTime(timezone=True)


def pg_enum(enum_cls: type[enum.Enum], name: str) -> Enum:
    """A Postgres ENUM whose labels are the member VALUES, not the member names.

    SQLAlchemy defaults to storing `ACCEPTED`, while the application and API both speak
    `accepted`. That split is invisible through the ORM and only surfaces later in raw SQL
    — CSV exports, ops queries, reporting — so pin it to values here, once.
    """
    return Enum(enum_cls, name=name, values_callable=lambda e: [m.value for m in e])
