import os
import time
import uuid
from datetime import datetime

from sqlalchemy import DateTime, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column


class Base(DeclarativeBase):
    pass


class TimestampMixin:
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), nullable=False
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        server_default=func.now(),
        onupdate=func.now(),
        nullable=False,
    )


def new_uuid() -> uuid.UUID:
    return uuid.uuid4()


def new_uuid7() -> uuid.UUID:
    """Generate a UUIDv7 (RFC 9562): 48-bit big-endian ms timestamp, version
    and variant bits, remaining bits random. Time-sortable, so primary keys
    generated with this helper order chronologically without a separate
    created_at index lookup — the identity layering canon
    (work-record-types_v0.1.md) calls this out as the primary internal key
    for new work-record entities.

    Dependency-free (no uuid7 in stdlib before Python 3.14, no third-party
    lib added for a ~15-line, non-cryptographic layout).
    """
    unix_ts_ms = int(time.time() * 1000)
    rand = int.from_bytes(os.urandom(10), "big")
    rand_a = (rand >> 62) & 0x0FFF          # top 12 bits of the 80 random bits
    rand_b = rand & 0x3FFFFFFFFFFFFFFF       # bottom 62 bits
    value = (
        (unix_ts_ms << 80)
        | (0x7 << 76)       # version 7
        | (rand_a << 64)
        | (0x2 << 62)        # variant 10
        | rand_b
    )
    return uuid.UUID(int=value)
