# #region DatasetReviewExecutionModels [C:3] [TYPE Module] [SEMANTICS sqlalchemy, dataset, review, execution, model]
# @BRIEF Compiled preview, run context, session event, and export artifact models for execution and audit.
# @LAYER Domain
# @RELATION DEPENDS_ON -> [DatasetReviewEnums]
# @RELATION DEPENDS_ON -> [MappingModels]

from datetime import UTC, datetime
import uuid

from sqlalchemy import (
    JSON,
    Column,
    DateTime,
    Enum as SQLEnum,
    ForeignKey,
    String,
    Text,
)
from sqlalchemy.orm import relationship

from src.models.dataset_review_pkg._enums import (
    ArtifactFormat,
    ArtifactType,
    LaunchStatus,
    PreviewStatus,
)
from src.models.mapping import Base


# #region CompiledPreview [C:2] [TYPE Class]
# @BRIEF One compiled SQL preview snapshot with fingerprint for staleness detection.
# @RELATION DEPENDS_ON -> [DatasetReviewSession]
class CompiledPreview(Base):
    __tablename__ = "compiled_previews"

    preview_id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    session_id = Column(
        String, ForeignKey("dataset_review_sessions.session_id"), nullable=False
    )
    preview_status = Column(
        SQLEnum(PreviewStatus), nullable=False, default=PreviewStatus.PENDING
    )
    compiled_sql = Column(Text, nullable=True)
    preview_fingerprint = Column(String, nullable=False)
    compiled_by = Column(String, nullable=False, default="superset")
    error_code = Column(String, nullable=True)
    error_details = Column(Text, nullable=True)
    compiled_at = Column(DateTime, nullable=True)
    created_at = Column(DateTime, default=lambda: datetime.now(UTC), nullable=False)

    session = relationship("DatasetReviewSession", back_populates="previews")


# #endregion CompiledPreview


# #region DatasetRunContext [C:2] [TYPE Class]
# @BRIEF Immutable launch audit snapshot capturing effective filters, template params, and approval state at launch time.
# @RELATION DEPENDS_ON -> [DatasetReviewSession]
class DatasetRunContext(Base):
    __tablename__ = "dataset_run_contexts"

    run_context_id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    session_id = Column(
        String, ForeignKey("dataset_review_sessions.session_id"), nullable=False
    )
    dataset_ref = Column(String, nullable=False)
    environment_id = Column(String, nullable=False)
    preview_id = Column(String, nullable=False)
    sql_lab_session_ref = Column(String, nullable=False)
    effective_filters = Column(JSON, nullable=False)
    template_params = Column(JSON, nullable=False)
    approved_mapping_ids = Column(JSON, nullable=False)
    semantic_decision_refs = Column(JSON, nullable=False)
    open_warning_refs = Column(JSON, nullable=False)
    launch_status = Column(SQLEnum(LaunchStatus), nullable=False)
    launch_error = Column(Text, nullable=True)
    created_at = Column(DateTime, default=lambda: datetime.now(UTC), nullable=False)

    session = relationship("DatasetReviewSession", back_populates="run_contexts")


# #endregion DatasetRunContext


# #region SessionEvent [C:2] [TYPE Class]
# @BRIEF One persisted audit event for dataset review session mutations.
# @RELATION DEPENDS_ON -> [DatasetReviewSession]
class SessionEvent(Base):
    __tablename__ = "session_events"

    session_event_id = Column(
        String, primary_key=True, default=lambda: str(uuid.uuid4())
    )
    session_id = Column(
        String, ForeignKey("dataset_review_sessions.session_id"), nullable=False
    )
    actor_user_id = Column(String, ForeignKey("users.id"), nullable=False)
    event_type = Column(String, nullable=False)
    event_summary = Column(Text, nullable=False)
    current_phase = Column(String, nullable=True)
    readiness_state = Column(String, nullable=True)
    event_details = Column(JSON, nullable=False, default=dict)
    created_at = Column(DateTime, default=lambda: datetime.now(UTC), nullable=False)

    session = relationship("DatasetReviewSession", back_populates="events")
    actor = relationship("User")


# #endregion SessionEvent


# #region ExportArtifact [C:2] [TYPE Class]
# @BRIEF One persisted export artifact reference for documentation and validation outputs.
# @RELATION DEPENDS_ON -> [DatasetReviewSession]
class ExportArtifact(Base):
    __tablename__ = "export_artifacts"

    artifact_id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    session_id = Column(
        String, ForeignKey("dataset_review_sessions.session_id"), nullable=False
    )
    artifact_type = Column(SQLEnum(ArtifactType), nullable=False)
    format = Column(SQLEnum(ArtifactFormat), nullable=False)
    storage_ref = Column(String, nullable=False)
    created_by_user_id = Column(String, nullable=False)
    created_at = Column(DateTime, default=lambda: datetime.now(UTC), nullable=False)

    session = relationship("DatasetReviewSession", back_populates="export_artifacts")


# #endregion ExportArtifact


# #endregion DatasetReviewExecutionModels
