# #region DatasetReviewMappingModels [C:2] [TYPE Module] [SEMANTICS sqlalchemy, dataset, review, mapping, model]
# @BRIEF Execution mapping model linking imported filters to template variables with approval gates.
# @LAYER Domain
# @RELATION DEPENDS_ON -> [DatasetReviewEnums]
# @RELATION DEPENDS_ON -> [MappingModels]

from datetime import UTC, datetime
import uuid

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

from src.models.dataset_review_pkg._enums import (
    ApprovalState,
    MappingMethod,
    MappingWarningLevel,
)
from src.models.mapping import Base


# #region ExecutionMapping [C:2] [TYPE Class]
# @BRIEF One filter-to-variable mapping with approval gate, effective value, and transformation metadata.
# @RELATION DEPENDS_ON -> [DatasetReviewSession]
# @INVARIANT  Explicit approval is required before launch when requires_explicit_approval is true.
class ExecutionMapping(Base):
    __tablename__ = "execution_mappings"

    mapping_id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    session_id = Column(String, ForeignKey("dataset_review_sessions.session_id"), nullable=False)
    filter_id = Column(String, nullable=False)
    variable_id = Column(String, nullable=False)
    mapping_method = Column(SQLEnum(MappingMethod), nullable=False)
    raw_input_value = Column(JSON, nullable=False)
    effective_value = Column(JSON, nullable=True)
    transformation_note = Column(Text, nullable=True)
    warning_level = Column(SQLEnum(MappingWarningLevel), nullable=True)
    requires_explicit_approval = Column(Boolean, nullable=False, default=False)
    approval_state = Column(SQLEnum(ApprovalState), nullable=False, default=ApprovalState.NOT_REQUIRED)
    approved_by_user_id = Column(String, nullable=True)
    approved_at = Column(DateTime, nullable=True)
    created_at = Column(DateTime, default=lambda: datetime.now(UTC), nullable=False)
    updated_at = Column(DateTime, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC), nullable=False)

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


# #endregion ExecutionMapping


# #endregion DatasetReviewMappingModels
