"""
Strategy Infrastructure — Mappers.

مپرهای Entity ↔ ORM Model.
"""

from ...domain.entities.vision import Vision
from ...domain.entities.strategic_theme import StrategicTheme
from ...domain.entities.objective import Objective
from ...domain.entities.key_result import KeyResult
from ...domain.entities.key_result_checkin import KeyResultCheckIn
from ...domain.entities.kpi_definition import KPIDefinition
from ...domain.entities.kpi_target import KPITarget
from ...domain.entities.kpi_actual import KPIActual
from ...domain.entities.kpi_assignment import KPIAssignment
from ...domain.entities.strategy_map import StrategyMap
from ...domain.entities.strategy_map_perspective import StrategyMapPerspective
from ...domain.entities.strategy_map_objective import StrategyMapObjective
from ...domain.entities.causal_link import CausalLink
from ...domain.entities.scorecard import Scorecard
from ...domain.entities.scorecard_perspective import ScorecardPerspective
from ...domain.entities.scorecard_measure import ScorecardMeasure
from ...domain.entities.gate_process import GateProcess
from ...domain.entities.gate import Gate
from ...domain.entities.gate_review import GateReview
from ...domain.entities.gate_reviewer import GateReviewer
from ...domain.entities.gate_deliverable import GateDeliverable
from ...domain.entities.policy import Policy
from ...domain.entities.policy_acknowledgment import PolicyAcknowledgment
from ..persistence.models import (
    VisionModel, StrategicThemeModel,
    ObjectiveModel, KeyResultModel, KeyResultCheckInModel,
    KPIDefinitionModel, KPITargetModel, KPIActualModel, KPIAssignmentModel,
    StrategyMapModel, StrategyMapPerspectiveModel,
    StrategyMapObjectiveModel, CausalLinkModel,
    ScorecardModel, ScorecardPerspectiveModel, ScorecardMeasureModel,
    GateProcessModel, GateModel, GateReviewModel,
    GateReviewerModel, GateDeliverableModel,
    PolicyModel, PolicyAcknowledgmentModel,
)


class VisionMapper:
    """مپر Vision Entity ↔ VisionModel."""

    @staticmethod
    def to_entity(model: VisionModel) -> Vision:
        return Vision(
            id=model.id,
            tenant_id=model.tenant_id,
            title=model.title,
            description=model.description,
            time_horizon_start=model.time_horizon_start,
            time_horizon_end=model.time_horizon_end,
            status=model.status,
            owner_id=model.owner_id,
            tags=model.tags or [],
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: Vision, model: VisionModel = None) -> VisionModel:
        if model is None:
            model = VisionModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.title = entity.title
        model.description = entity.description
        model.time_horizon_start = entity.time_horizon_start
        model.time_horizon_end = entity.time_horizon_end
        model.status = entity.status
        model.owner_id = entity.owner_id
        model.tags = entity.tags or []
        model.metadata = entity.metadata or {}
        return model


class StrategicThemeMapper:
    """مپر StrategicTheme Entity ↔ StrategicThemeModel."""

    @staticmethod
    def to_entity(model: StrategicThemeModel) -> StrategicTheme:
        return StrategicTheme(
            id=model.id,
            tenant_id=model.tenant_id,
            vision_id=model.vision_id,
            name=model.name,
            description=model.description,
            priority=model.priority,
            status=model.status,
            owner_id=model.owner_id,
            start_date=model.start_date,
            end_date=model.end_date,
            sort_order=model.sort_order,
            tags=model.tags or [],
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: StrategicTheme, model: StrategicThemeModel = None) -> StrategicThemeModel:
        if model is None:
            model = StrategicThemeModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.vision_id = entity.vision_id
        model.name = entity.name
        model.description = entity.description
        model.priority = entity.priority
        model.status = entity.status
        model.owner_id = entity.owner_id
        model.start_date = entity.start_date
        model.end_date = entity.end_date
        model.sort_order = entity.sort_order
        model.tags = entity.tags or []
        model.metadata = entity.metadata or {}
        return model


class ObjectiveMapper:
    """مپر Objective Entity ↔ ObjectiveModel."""

    @staticmethod
    def to_entity(model: ObjectiveModel) -> Objective:
        return Objective(
            id=model.id,
            tenant_id=model.tenant_id,
            theme_id=model.theme_id,
            parent_id=model.parent_id,
            title=model.title,
            description=model.description,
            level=model.level,
            time_frame=model.time_frame,
            period_start=model.period_start,
            period_end=model.period_end,
            status=model.status,
            weight=model.weight,
            progress=model.progress,
            owner_id=model.owner_id,
            tags=model.tags or [],
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: Objective, model: ObjectiveModel = None) -> ObjectiveModel:
        if model is None:
            model = ObjectiveModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.theme_id = entity.theme_id
        model.parent_id = entity.parent_id
        model.title = entity.title
        model.description = entity.description
        model.level = entity.level
        model.time_frame = entity.time_frame
        model.period_start = entity.period_start
        model.period_end = entity.period_end
        model.status = entity.status
        model.weight = entity.weight
        model.progress = entity.progress
        model.owner_id = entity.owner_id
        model.tags = entity.tags or []
        model.metadata = entity.metadata or {}
        return model


class KeyResultMapper:
    """مپر KeyResult Entity ↔ KeyResultModel."""

    @staticmethod
    def to_entity(model: KeyResultModel) -> KeyResult:
        return KeyResult(
            id=model.id,
            tenant_id=model.tenant_id,
            objective_id=model.objective_id,
            title=model.title,
            metric_type=model.metric_type,
            start_value=model.start_value,
            target_value=model.target_value,
            current_value=model.current_value,
            weight=model.weight,
            status=model.status,
            owner_id=model.owner_id,
            due_date=model.due_date,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: KeyResult, model: KeyResultModel = None) -> KeyResultModel:
        if model is None:
            model = KeyResultModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.objective_id = entity.objective_id
        model.title = entity.title
        model.metric_type = entity.metric_type
        model.start_value = entity.start_value
        model.target_value = entity.target_value
        model.current_value = entity.current_value
        model.weight = entity.weight
        model.status = entity.status
        model.owner_id = entity.owner_id
        model.due_date = entity.due_date
        model.metadata = entity.metadata or {}
        return model


class KeyResultCheckInMapper:
    """مپر KeyResultCheckIn Entity ↔ KeyResultCheckInModel."""

    @staticmethod
    def to_entity(model: KeyResultCheckInModel) -> KeyResultCheckIn:
        return KeyResultCheckIn(
            id=model.id,
            tenant_id=model.tenant_id,
            key_result_id=model.key_result_id,
            value=model.value,
            confidence=model.confidence,
            notes=model.notes,
            checked_by=model.checked_by_id,
            check_date=model.check_date,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: KeyResultCheckIn, model: KeyResultCheckInModel = None) -> KeyResultCheckInModel:
        if model is None:
            model = KeyResultCheckInModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.key_result_id = entity.key_result_id
        model.value = entity.value
        model.confidence = entity.confidence
        model.notes = entity.notes
        model.checked_by_id = entity.checked_by
        model.metadata = entity.metadata or {}
        return model


class KPIDefinitionMapper:
    """مپر KPIDefinition Entity ↔ KPIDefinitionModel."""

    @staticmethod
    def to_entity(model: KPIDefinitionModel) -> KPIDefinition:
        return KPIDefinition(
            id=model.id,
            tenant_id=model.tenant_id,
            name=model.name,
            code=model.code,
            description=model.description,
            category=model.category,
            unit_of_measure=model.unit_of_measure,
            direction=model.direction,
            frequency=model.frequency,
            data_source=model.data_source,
            formula=model.formula,
            threshold_red=float(model.threshold_red) if model.threshold_red is not None else None,
            threshold_yellow=float(model.threshold_yellow) if model.threshold_yellow is not None else None,
            threshold_green=float(model.threshold_green) if model.threshold_green is not None else None,
            owner_id=model.owner_id,
            responsible_role=model.responsible_role,
            status=model.status,
            tags=model.tags or [],
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: KPIDefinition, model: KPIDefinitionModel = None) -> KPIDefinitionModel:
        if model is None:
            model = KPIDefinitionModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.name = entity.name
        model.code = entity.code
        model.description = entity.description
        model.category = entity.category
        model.unit_of_measure = entity.unit_of_measure
        model.direction = entity.direction
        model.frequency = entity.frequency
        model.data_source = entity.data_source
        model.formula = entity.formula
        model.threshold_red = entity.threshold_red
        model.threshold_yellow = entity.threshold_yellow
        model.threshold_green = entity.threshold_green
        model.owner_id = entity.owner_id
        model.responsible_role = entity.responsible_role
        model.status = entity.status
        model.tags = entity.tags or []
        model.metadata = entity.metadata or {}
        return model


class KPITargetMapper:
    """مپر KPITarget Entity ↔ KPITargetModel."""

    @staticmethod
    def to_entity(model: KPITargetModel) -> KPITarget:
        return KPITarget(
            id=model.id,
            tenant_id=model.tenant_id,
            kpi_id=model.kpi_id,
            period_start=model.period_start,
            period_end=model.period_end,
            target_value=float(model.target_value),
            stretch_value=float(model.stretch_value) if model.stretch_value is not None else None,
            notes=model.notes,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: KPITarget, model: KPITargetModel = None) -> KPITargetModel:
        if model is None:
            model = KPITargetModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.kpi_id = entity.kpi_id
        model.period_start = entity.period_start
        model.period_end = entity.period_end
        model.target_value = entity.target_value
        model.stretch_value = entity.stretch_value
        model.notes = entity.notes
        model.metadata = entity.metadata or {}
        return model


class KPIActualMapper:
    """مپر KPIActual Entity ↔ KPIActualModel."""

    @staticmethod
    def to_entity(model: KPIActualModel) -> KPIActual:
        return KPIActual(
            id=model.id,
            tenant_id=model.tenant_id,
            kpi_id=model.kpi_id,
            period_start=model.period_start,
            period_end=model.period_end,
            actual_value=float(model.actual_value),
            notes=model.notes,
            source=model.source,
            recorded_by=model.recorded_by_id,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: KPIActual, model: KPIActualModel = None) -> KPIActualModel:
        if model is None:
            model = KPIActualModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.kpi_id = entity.kpi_id
        model.period_start = entity.period_start
        model.period_end = entity.period_end
        model.actual_value = entity.actual_value
        model.notes = entity.notes
        model.source = entity.source
        model.recorded_by_id = entity.recorded_by
        model.metadata = entity.metadata or {}
        return model


class KPIAssignmentMapper:
    """مپر KPIAssignment Entity ↔ KPIAssignmentModel."""

    @staticmethod
    def to_entity(model: KPIAssignmentModel) -> KPIAssignment:
        return KPIAssignment(
            id=model.id,
            tenant_id=model.tenant_id,
            kpi_id=model.kpi_id,
            level=model.level,
            entity_id=model.entity_id,
            weight=float(model.weight),
            status=model.status,
            notes=model.notes,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: KPIAssignment, model: KPIAssignmentModel = None) -> KPIAssignmentModel:
        if model is None:
            model = KPIAssignmentModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.kpi_id = entity.kpi_id
        model.level = entity.level
        model.entity_id = entity.entity_id
        model.weight = entity.weight
        model.status = entity.status
        model.notes = entity.notes
        model.metadata = entity.metadata or {}
        return model


# ═══════════════════════════════════════════════════
# StrategyMap Mapper
# ═══════════════════════════════════════════════════

class StrategyMapMapper:
    """مپر StrategyMap Entity ↔ StrategyMapModel."""

    @staticmethod
    def to_entity(model: StrategyMapModel) -> StrategyMap:
        return StrategyMap(
            id=model.id,
            tenant_id=model.tenant_id,
            name=model.name,
            description=model.description,
            version=model.version,
            status=model.status,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: StrategyMap, model: StrategyMapModel = None) -> StrategyMapModel:
        if model is None:
            model = StrategyMapModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.name = entity.name
        model.description = entity.description
        model.version = entity.version
        model.status = entity.status
        model.metadata = entity.metadata or {}
        return model


# ═══════════════════════════════════════════════════
# StrategyMapPerspective Mapper
# ═══════════════════════════════════════════════════

class StrategyMapPerspectiveMapper:
    """مپر StrategyMapPerspective Entity ↔ StrategyMapPerspectiveModel."""

    @staticmethod
    def to_entity(model: StrategyMapPerspectiveModel) -> StrategyMapPerspective:
        return StrategyMapPerspective(
            id=model.id,
            tenant_id=model.tenant_id,
            map_id=model.strategy_map_id,
            name=model.name,
            description=model.description,
            sort_order=model.sort_order,
            color=model.color,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: StrategyMapPerspective, model: StrategyMapPerspectiveModel = None) -> StrategyMapPerspectiveModel:
        if model is None:
            model = StrategyMapPerspectiveModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.strategy_map_id = entity.map_id
        model.name = entity.name
        model.description = entity.description
        model.sort_order = entity.sort_order
        model.color = entity.color
        model.metadata = entity.metadata or {}
        return model


# ═══════════════════════════════════════════════════
# StrategyMapObjective Mapper
# ═══════════════════════════════════════════════════

class StrategyMapObjectiveMapper:
    """مپر StrategyMapObjective Entity ↔ StrategyMapObjectiveModel."""

    @staticmethod
    def to_entity(model: StrategyMapObjectiveModel) -> StrategyMapObjective:
        return StrategyMapObjective(
            id=model.id,
            tenant_id=model.tenant_id,
            map_id=model.strategy_map_id,
            perspective_id=model.perspective_id,
            objective_id=model.objective_id,
            x_position=model.x_position,
            y_position=model.y_position,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: StrategyMapObjective, model: StrategyMapObjectiveModel = None) -> StrategyMapObjectiveModel:
        if model is None:
            model = StrategyMapObjectiveModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.strategy_map_id = entity.map_id
        model.perspective_id = entity.perspective_id
        model.objective_id = entity.objective_id
        model.x_position = entity.x_position
        model.y_position = entity.y_position
        model.metadata = entity.metadata or {}
        return model


# ═══════════════════════════════════════════════════
# CausalLink Mapper
# ═══════════════════════════════════════════════════

class CausalLinkMapper:
    """مپر CausalLink Entity ↔ CausalLinkModel."""

    @staticmethod
    def to_entity(model: CausalLinkModel) -> CausalLink:
        return CausalLink(
            id=model.id,
            tenant_id=model.tenant_id,
            map_id=model.strategy_map_id,
            from_objective_id=model.from_objective_id,
            to_objective_id=model.to_objective_id,
            strength=model.strength,
            description=model.description,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: CausalLink, model: CausalLinkModel = None) -> CausalLinkModel:
        if model is None:
            model = CausalLinkModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.strategy_map_id = entity.map_id
        model.from_objective_id = entity.from_objective_id
        model.to_objective_id = entity.to_objective_id
        model.strength = entity.strength
        model.description = entity.description
        model.metadata = entity.metadata or {}
        return model


# ═══════════════════════════════════════════════════
# Scorecard Mapper
# ═══════════════════════════════════════════════════

class ScorecardMapper:
    """مپر Scorecard Entity ↔ ScorecardModel."""

    @staticmethod
    def to_entity(model: ScorecardModel) -> Scorecard:
        return Scorecard(
            id=model.id,
            tenant_id=model.tenant_id,
            name=model.name,
            description=model.description,
            owner_id=model.owner_id,
            period_start=model.period_start,
            period_end=model.period_end,
            status=model.status,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: Scorecard, model: ScorecardModel = None) -> ScorecardModel:
        if model is None:
            model = ScorecardModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.name = entity.name
        model.description = entity.description
        model.owner_id = entity.owner_id
        model.period_start = entity.period_start
        model.period_end = entity.period_end
        model.status = entity.status
        model.metadata = entity.metadata or {}
        return model


# ═══════════════════════════════════════════════════
# ScorecardPerspective Mapper
# ═══════════════════════════════════════════════════

class ScorecardPerspectiveMapper:
    """مپر ScorecardPerspective Entity ↔ ScorecardPerspectiveModel."""

    @staticmethod
    def to_entity(model: ScorecardPerspectiveModel) -> ScorecardPerspective:
        return ScorecardPerspective(
            id=model.id,
            tenant_id=model.tenant_id,
            scorecard_id=model.scorecard_id,
            name=model.name,
            weight=float(model.weight),
            sort_order=model.sort_order,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: ScorecardPerspective, model: ScorecardPerspectiveModel = None) -> ScorecardPerspectiveModel:
        if model is None:
            model = ScorecardPerspectiveModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.scorecard_id = entity.scorecard_id
        model.name = entity.name
        model.weight = entity.weight
        model.sort_order = entity.sort_order
        model.metadata = entity.metadata or {}
        return model


# ═══════════════════════════════════════════════════
# ScorecardMeasure Mapper
# ═══════════════════════════════════════════════════

class ScorecardMeasureMapper:
    """مپر ScorecardMeasure Entity ↔ ScorecardMeasureModel."""

    @staticmethod
    def to_entity(model: ScorecardMeasureModel) -> ScorecardMeasure:
        return ScorecardMeasure(
            id=model.id,
            tenant_id=model.tenant_id,
            perspective_id=model.perspective_id,
            kpi_assignment_id=model.kpi_assignment_id,
            weight=float(model.weight),
            target_value=float(model.target_value),
            actual_value=float(model.actual_value),
            score=float(model.score),
            status=model.status,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: ScorecardMeasure, model: ScorecardMeasureModel = None) -> ScorecardMeasureModel:
        if model is None:
            model = ScorecardMeasureModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.perspective_id = entity.perspective_id
        model.kpi_assignment_id = entity.kpi_assignment_id
        model.weight = entity.weight
        model.target_value = entity.target_value
        model.actual_value = entity.actual_value
        model.score = entity.score
        model.status = entity.status
        model.metadata = entity.metadata or {}
        return model


# ═══════════════════════════════════════════════════
# Stage-Gate Governance Mappers
# ═══════════════════════════════════════════════════

class GateProcessMapper:
    """مپر GateProcess Entity ↔ GateProcessModel."""

    @staticmethod
    def to_entity(model: GateProcessModel) -> GateProcess:
        return GateProcess(
            id=model.id,
            tenant_id=model.tenant_id,
            name=model.name,
            description=model.description,
            applicable_to=model.applicable_to,
            is_active=model.is_active,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: GateProcess, model: GateProcessModel = None) -> GateProcessModel:
        if model is None:
            model = GateProcessModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.name = entity.name
        model.description = entity.description
        model.applicable_to = entity.applicable_to
        model.is_active = entity.is_active
        model.metadata = entity.metadata or {}
        return model


class GateMapper:
    """مپر Gate Entity ↔ GateModel."""

    @staticmethod
    def to_entity(model: GateModel) -> Gate:
        return Gate(
            id=model.id,
            tenant_id=model.tenant_id,
            process_id=model.process_id,
            name=model.name,
            sequence=model.sequence,
            description=model.description,
            mandatory_deliverables=model.mandatory_deliverables or [],
            criteria=model.criteria,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: Gate, model: GateModel = None) -> GateModel:
        if model is None:
            model = GateModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.process_id = entity.process_id
        model.name = entity.name
        model.sequence = entity.sequence
        model.description = entity.description
        model.mandatory_deliverables = entity.mandatory_deliverables or []
        model.criteria = entity.criteria
        model.metadata = entity.metadata or {}
        return model


class GateReviewMapper:
    """مپر GateReview Entity ↔ GateReviewModel."""

    @staticmethod
    def to_entity(model: GateReviewModel) -> GateReview:
        return GateReview(
            id=model.id,
            tenant_id=model.tenant_id,
            gate_id=model.gate_id,
            entity_id=model.entity_id,
            entity_type=model.entity_type,
            status=model.status,
            review_date=model.review_date,
            notes=model.notes,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: GateReview, model: GateReviewModel = None) -> GateReviewModel:
        if model is None:
            model = GateReviewModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.gate_id = entity.gate_id
        model.entity_id = entity.entity_id
        model.entity_type = entity.entity_type
        model.status = entity.status
        model.review_date = entity.review_date
        model.notes = entity.notes
        model.metadata = entity.metadata or {}
        return model


class GateReviewerMapper:
    """مپر GateReviewer Entity ↔ GateReviewerModel."""

    @staticmethod
    def to_entity(model: GateReviewerModel) -> GateReviewer:
        return GateReviewer(
            id=model.id,
            tenant_id=model.tenant_id,
            review_id=model.review_id,
            user_id=model.user_id,
            role=model.role,
            decision=model.decision,
            comments=model.comments,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: GateReviewer, model: GateReviewerModel = None) -> GateReviewerModel:
        if model is None:
            model = GateReviewerModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.review_id = entity.review_id
        model.user_id = entity.user_id
        model.role = entity.role
        model.decision = entity.decision
        model.comments = entity.comments
        model.metadata = entity.metadata or {}
        return model


class GateDeliverableMapper:
    """مپر GateDeliverable Entity ↔ GateDeliverableModel."""

    @staticmethod
    def to_entity(model: GateDeliverableModel) -> GateDeliverable:
        return GateDeliverable(
            id=model.id,
            tenant_id=model.tenant_id,
            review_id=model.review_id,
            name=model.name,
            status=model.status,
            document_id=model.document_id,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: GateDeliverable, model: GateDeliverableModel = None) -> GateDeliverableModel:
        if model is None:
            model = GateDeliverableModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.review_id = entity.review_id
        model.name = entity.name
        model.status = entity.status
        model.document_id = entity.document_id
        model.metadata = entity.metadata or {}
        return model


# ═══════════════════════════════════════════════════
# Corporate Policy Management Mappers
# ═══════════════════════════════════════════════════

class PolicyMapper:
    """مپر Policy Entity ↔ PolicyModel."""

    @staticmethod
    def to_entity(model: PolicyModel) -> Policy:
        return Policy(
            id=model.id,
            tenant_id=model.tenant_id,
            title=model.title,
            code=model.code,
            category=model.category,
            content=model.content,
            version=model.version,
            status=model.status,
            effective_date=model.effective_date,
            review_date=model.review_date,
            owner_id=model.owner_id,
            approver_id=model.approver_id,
            document_id=model.document_id,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: Policy, model: PolicyModel = None) -> PolicyModel:
        if model is None:
            model = PolicyModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.title = entity.title
        model.code = entity.code
        model.category = entity.category
        model.content = entity.content
        model.version = entity.version
        model.status = entity.status
        model.effective_date = entity.effective_date
        model.review_date = entity.review_date
        model.owner_id = entity.owner_id
        model.approver_id = entity.approver_id
        model.document_id = entity.document_id
        model.metadata = entity.metadata or {}
        return model


class PolicyAcknowledgmentMapper:
    """مپر PolicyAcknowledgment Entity ↔ PolicyAcknowledgmentModel."""

    @staticmethod
    def to_entity(model: PolicyAcknowledgmentModel) -> PolicyAcknowledgment:
        return PolicyAcknowledgment(
            id=model.id,
            tenant_id=model.tenant_id,
            policy_id=model.policy_id,
            user_id=model.user_id,
            acknowledged_at=model.acknowledged_at,
            metadata=model.metadata or {},
            created_at=model.created_at,
            updated_at=model.updated_at,
        )

    @staticmethod
    def to_model(entity: PolicyAcknowledgment, model: PolicyAcknowledgmentModel = None) -> PolicyAcknowledgmentModel:
        if model is None:
            model = PolicyAcknowledgmentModel(id=entity.id)
        model.tenant_id = entity.tenant_id
        model.policy_id = entity.policy_id
        model.user_id = entity.user_id
        model.acknowledged_at = entity.acknowledged_at
        model.metadata = entity.metadata or {}
        return model
