import enum
import uuid
from datetime import datetime

from sqlalchemy import DateTime, Enum, Float, String, func
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column

from app.models.base import Base, UUIDPKMixin


class MergeKind(str, enum.Enum):
    scene = "scene"
    performer = "performer"
    studio = "studio"
    movie = "movie"


class MergeStatus(str, enum.Enum):
    pending = "pending"
    auto_merged = "auto_merged"
    merged = "merged"
    rejected = "rejected"


class MergeCandidate(UUIDPKMixin, Base):
    __tablename__ = "merge_candidates"

    kind: Mapped[MergeKind] = mapped_column(Enum(MergeKind, name="merge_kind"), nullable=False)
    left_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), nullable=False, index=True)
    right_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), nullable=False, index=True)
    score: Mapped[float] = mapped_column(Float, nullable=False)
    reasons: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict)
    status: Mapped[MergeStatus] = mapped_column(
        Enum(MergeStatus, name="merge_status"),
        nullable=False,
        default=MergeStatus.pending,
        server_default=MergeStatus.pending.value,
        index=True,
    )
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), nullable=False
    )
    resolved_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    resolved_by: Mapped[str | None] = mapped_column(String(128))
