from __future__ import annotations

import uuid
from datetime import datetime

from sqlalchemy import CheckConstraint, DateTime, String, UniqueConstraint
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column

from api.models.base import Base, TimestampMixin, new_uuid


class WorkRecordIdentifierAlias(Base, TimestampMixin):
    """Durable provenance for a canonical work-record UUID replacement."""

    __tablename__ = "work_record_identifier_aliases"
    __table_args__ = (
        CheckConstraint(
            "record_kind IN ('workplan', 'task')",
            name="ck_work_record_identifier_aliases_kind",
        ),
        CheckConstraint(
            "migration_status IN ('prepared', 'applied', 'reversed')",
            name="ck_work_record_identifier_aliases_status",
        ),
        UniqueConstraint("old_id", name="uq_work_record_identifier_aliases_old_id"),
        UniqueConstraint("new_id", name="uq_work_record_identifier_aliases_new_id"),
    )

    id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True), primary_key=True, default=new_uuid
    )
    old_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), nullable=False)
    new_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), nullable=False)
    record_kind: Mapped[str] = mapped_column(String(20), nullable=False)
    record_id: Mapped[str] = mapped_column(String(160), nullable=False, index=True)
    repo_slug: Mapped[str] = mapped_column(String(100), nullable=False, index=True)
    namespace: Mapped[str] = mapped_column(String(64), nullable=False)
    plan_sha256: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
    migration_status: Mapped[str] = mapped_column(
        String(20), nullable=False, default="prepared", server_default="prepared"
    )
    applied_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    reversed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
