"""
Strategy ORM Models — Infrastructure Layer.

مدل‌های Django ORM ماژول مدیریت راهبرد و حاکمیت.
تمام جداول با پیشوند str_ هستند.
"""
import uuid

from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _
from apps.core.tenant.models import TenantAwareModel


# ═══════════════════════════════════════════════════
# 1️⃣ Vision
# ═══════════════════════════════════════════════════

class VisionModel(TenantAwareModel):
    """مدل ORM — چشم‌انداز سازمانی."""

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        ACTIVE = "active", _("فعال")
        ARCHIVED = "archived", _("بایگانی")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_("عنوان"), max_length=500)
    description = models.TextField(_("توضیحات"), blank=True)

    time_horizon_start = models.DateField(_("شروع افق زمانی"), null=True, blank=True)
    time_horizon_end = models.DateField(_("پایان افق زمانی"), null=True, blank=True)

    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT,
    )

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="owned_visions",
        verbose_name=_("مالک"),
    )

    tags = models.JSONField(_("برچسب‌ها"), default=list, blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_vision"
        verbose_name = _("چشم‌انداز")
        verbose_name_plural = _("چشم‌اندازها")
        ordering = ["-created_at"]

    def __str__(self):
        return self.title


# ═══════════════════════════════════════════════════
# 2️⃣ StrategicTheme
# ═══════════════════════════════════════════════════

class StrategicThemeModel(TenantAwareModel):
    """مدل ORM — تم راهبردی."""

    class Priority(models.TextChoices):
        LOW = "low", _("کم")
        MEDIUM = "medium", _("متوسط")
        HIGH = "high", _("زیاد")
        CRITICAL = "critical", _("بحرانی")

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        ACTIVE = "active", _("فعال")
        COMPLETED = "completed", _("تکمیل‌شده")
        ARCHIVED = "archived", _("بایگانی")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    vision = models.ForeignKey(
        VisionModel, on_delete=models.CASCADE,
        related_name="themes",
        verbose_name=_("چشم‌انداز"),
    )

    name = models.CharField(_("نام"), max_length=500)
    description = models.TextField(_("توضیحات"), blank=True)

    priority = models.CharField(
        _("اولویت"), max_length=20,
        choices=Priority.choices, default=Priority.MEDIUM,
    )
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT,
    )

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="owned_themes",
        verbose_name=_("مالک"),
    )

    start_date = models.DateField(_("تاریخ شروع"), null=True, blank=True)
    end_date = models.DateField(_("تاریخ پایان"), null=True, blank=True)

    sort_order = models.PositiveIntegerField(_("ترتیب"), default=0)

    tags = models.JSONField(_("برچسب‌ها"), default=list, blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_strategic_theme"
        verbose_name = _("تم راهبردی")
        verbose_name_plural = _("تم‌های راهبردی")
        ordering = ["sort_order", "-created_at"]

    def __str__(self):
        return self.name


# ═══════════════════════════════════════════════════
# 3️⃣ Objective
# ═══════════════════════════════════════════════════

class ObjectiveModel(TenantAwareModel):
    """مدل ORM — هدف راهبردی (OKR Objective)."""

    class Level(models.TextChoices):
        ENTERPRISE = "enterprise", _("سازمانی")
        BUSINESS_UNIT = "business_unit", _("واحد کسب‌وکار")
        DEPARTMENT = "department", _("دپارتمان")
        TEAM = "team", _("تیم")

    class TimeFrame(models.TextChoices):
        ANNUAL = "annual", _("سالانه")
        QUARTERLY = "quarterly", _("سه‌ماهه")

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        ACTIVE = "active", _("فعال")
        AT_RISK = "at_risk", _("در خطر")
        ACHIEVED = "achieved", _("محقق‌شده")
        MISSED = "missed", _("عدم تحقق")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    theme = models.ForeignKey(
        StrategicThemeModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="objectives",
        verbose_name=_("تم راهبردی"),
    )
    parent = models.ForeignKey(
        "self", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="children",
        verbose_name=_("هدف مادر"),
    )

    title = models.CharField(_("عنوان"), max_length=500)
    description = models.TextField(_("توضیحات"), blank=True)

    level = models.CharField(
        _("سطح"), max_length=20,
        choices=Level.choices, default=Level.ENTERPRISE,
    )
    time_frame = models.CharField(
        _("بازه زمانی"), max_length=20,
        choices=TimeFrame.choices, default=TimeFrame.ANNUAL,
    )

    period_start = models.DateField(_("شروع دوره"), null=True, blank=True)
    period_end = models.DateField(_("پایان دوره"), null=True, blank=True)

    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT,
    )

    weight = models.DecimalField(
        _("وزن"), max_digits=5, decimal_places=2, default=1.00,
    )
    progress = models.DecimalField(
        _("پیشرفت"), max_digits=5, decimal_places=2, default=0.00,
    )

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="owned_objectives",
        verbose_name=_("مالک"),
    )

    tags = models.JSONField(_("برچسب‌ها"), default=list, blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_objective"
        verbose_name = _("هدف")
        verbose_name_plural = _("اهداف")
        ordering = ["-created_at"]

    def __str__(self):
        return self.title


# ═══════════════════════════════════════════════════
# 4️⃣ KeyResult
# ═══════════════════════════════════════════════════

class KeyResultModel(TenantAwareModel):
    """مدل ORM — نتیجه کلیدی (OKR Key Result)."""

    class MetricType(models.TextChoices):
        NUMBER = "number", _("عددی")
        PERCENTAGE = "percentage", _("درصدی")
        CURRENCY = "currency", _("ارزی")
        BOOLEAN = "boolean", _("بله/خیر")

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        ACTIVE = "active", _("فعال")
        AT_RISK = "at_risk", _("در خطر")
        ACHIEVED = "achieved", _("محقق‌شده")
        MISSED = "missed", _("عدم تحقق")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    objective = models.ForeignKey(
        ObjectiveModel, on_delete=models.CASCADE,
        related_name="key_results",
        verbose_name=_("هدف"),
    )

    title = models.CharField(_("عنوان"), max_length=500)

    metric_type = models.CharField(
        _("نوع سنجه"), max_length=20,
        choices=MetricType.choices, default=MetricType.NUMBER,
    )
    start_value = models.DecimalField(
        _("مقدار شروع"), max_digits=15, decimal_places=2, default=0,
    )
    target_value = models.DecimalField(
        _("مقدار هدف"), max_digits=15, decimal_places=2, default=100,
    )
    current_value = models.DecimalField(
        _("مقدار فعلی"), max_digits=15, decimal_places=2, default=0,
    )

    weight = models.DecimalField(
        _("وزن"), max_digits=5, decimal_places=2, default=1.00,
    )
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT,
    )

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="owned_key_results",
        verbose_name=_("مالک"),
    )

    due_date = models.DateField(_("مهلت"), null=True, blank=True)

    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_key_result"
        verbose_name = _("نتیجه کلیدی")
        verbose_name_plural = _("نتایج کلیدی")
        ordering = ["-created_at"]

    def __str__(self):
        return self.title


# ═══════════════════════════════════════════════════
# 5️⃣ KeyResultCheckIn
# ═══════════════════════════════════════════════════

class KeyResultCheckInModel(TenantAwareModel):
    """مدل ORM — ثبت پیشرفت نتیجه کلیدی."""

    class Confidence(models.TextChoices):
        LOW = "low", _("پایین")
        MEDIUM = "medium", _("متوسط")
        HIGH = "high", _("بالا")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    key_result = models.ForeignKey(
        KeyResultModel, on_delete=models.CASCADE,
        related_name="check_ins",
        verbose_name=_("نتیجه کلیدی"),
    )

    value = models.DecimalField(
        _("مقدار"), max_digits=15, decimal_places=2,
    )
    confidence = models.CharField(
        _("سطح اطمینان"), max_length=10,
        choices=Confidence.choices, default=Confidence.MEDIUM,
    )
    notes = models.TextField(_("یادداشت"), blank=True)

    checked_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="check_ins",
        verbose_name=_("ثبت‌کننده"),
    )
    check_date = models.DateField(_("تاریخ ثبت"), auto_now_add=True)

    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_key_result_checkin"
        verbose_name = _("ثبت پیشرفت")
        verbose_name_plural = _("ثبت‌های پیشرفت")
        ordering = ["-check_date", "-created_at"]

    def __str__(self):
        return f"CheckIn {self.check_date} — {self.value}"


# ═══════════════════════════════════════════════════
# 6️⃣ KPIDefinition
# ═══════════════════════════════════════════════════

class KPIDefinitionModel(TenantAwareModel):
    """مدل ORM — شاخص کلیدی عملکرد."""

    class Direction(models.TextChoices):
        HIGHER_IS_BETTER = "higher_is_better", _("بالاتر بهتر")
        LOWER_IS_BETTER = "lower_is_better", _("پایین‌تر بهتر")
        TARGET = "target", _("هدف مشخص")

    class Frequency(models.TextChoices):
        DAILY = "daily", _("روزانه")
        WEEKLY = "weekly", _("هفتگی")
        MONTHLY = "monthly", _("ماهانه")
        QUARTERLY = "quarterly", _("سه‌ماهه")
        YEARLY = "yearly", _("سالانه")

    class DataSource(models.TextChoices):
        MANUAL = "manual", _("دستی")
        CALCULATED = "calculated", _("محاسباتی")
        INTEGRATED = "integrated", _("یکپارچه")

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        ACTIVE = "active", _("فعال")
        ARCHIVED = "archived", _("بایگانی")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("نام"), max_length=500)
    code = models.CharField(_("کد"), max_length=100, db_index=True)
    description = models.TextField(_("توضیحات"), blank=True)
    category = models.CharField(_("دسته‌بندی"), max_length=200, blank=True)
    unit_of_measure = models.CharField(_("واحد اندازه‌گیری"), max_length=100, blank=True)

    direction = models.CharField(
        _("جهت"), max_length=20,
        choices=Direction.choices, default=Direction.HIGHER_IS_BETTER,
    )
    frequency = models.CharField(
        _("فراوانی"), max_length=20,
        choices=Frequency.choices, default=Frequency.MONTHLY,
    )
    data_source = models.CharField(
        _("منبع داده"), max_length=20,
        choices=DataSource.choices, default=DataSource.MANUAL,
    )

    formula = models.TextField(_("فرمول محاسبه"), blank=True, null=True)

    threshold_red = models.DecimalField(
        _("آستانه قرمز"), max_digits=15, decimal_places=2, null=True, blank=True,
    )
    threshold_yellow = models.DecimalField(
        _("آستانه زرد"), max_digits=15, decimal_places=2, null=True, blank=True,
    )
    threshold_green = models.DecimalField(
        _("آستانه سبز"), max_digits=15, decimal_places=2, null=True, blank=True,
    )

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="owned_kpis",
        verbose_name=_("مالک"),
    )
    responsible_role = models.CharField(_("نقش مسئول"), max_length=200, blank=True)

    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT,
    )

    tags = models.JSONField(_("برچسب‌ها"), default=list, blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_kpi_definition"
        verbose_name = _("شاخص کلیدی عملکرد")
        verbose_name_plural = _("شاخص‌های کلیدی عملکرد")
        ordering = ["name"]
        unique_together = [("tenant", "code")]

    def __str__(self):
        return f"[{self.code}] {self.name}"


# ═══════════════════════════════════════════════════
# 7️⃣ KPITarget
# ═══════════════════════════════════════════════════

class KPITargetModel(TenantAwareModel):
    """مدل ORM — هدف‌گذاری KPI."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    kpi = models.ForeignKey(
        KPIDefinitionModel, on_delete=models.CASCADE,
        related_name="targets",
        verbose_name=_("شاخص"),
    )

    period_start = models.DateField(_("شروع دوره"), null=True, blank=True)
    period_end = models.DateField(_("پایان دوره"), null=True, blank=True)

    target_value = models.DecimalField(
        _("مقدار هدف"), max_digits=15, decimal_places=2, default=0,
    )
    stretch_value = models.DecimalField(
        _("مقدار چالشی"), max_digits=15, decimal_places=2, null=True, blank=True,
    )

    notes = models.TextField(_("یادداشت"), blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_kpi_target"
        verbose_name = _("هدف‌گذاری KPI")
        verbose_name_plural = _("هدف‌گذاری‌های KPI")
        ordering = ["-period_start"]

    def __str__(self):
        return f"Target {self.kpi} — {self.target_value}"


# ═══════════════════════════════════════════════════
# 8️⃣ KPIActual
# ═══════════════════════════════════════════════════

class KPIActualModel(TenantAwareModel):
    """مدل ORM — مقدار واقعی KPI."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    kpi = models.ForeignKey(
        KPIDefinitionModel, on_delete=models.CASCADE,
        related_name="actuals",
        verbose_name=_("شاخص"),
    )

    period_start = models.DateField(_("شروع دوره"), null=True, blank=True)
    period_end = models.DateField(_("پایان دوره"), null=True, blank=True)

    actual_value = models.DecimalField(
        _("مقدار واقعی"), max_digits=15, decimal_places=2, default=0,
    )

    notes = models.TextField(_("یادداشت"), blank=True)
    source = models.CharField(_("منبع"), max_length=50, default="manual")

    recorded_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="recorded_kpi_actuals",
        verbose_name=_("ثبت‌کننده"),
    )

    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_kpi_actual"
        verbose_name = _("مقدار واقعی KPI")
        verbose_name_plural = _("مقادیر واقعی KPI")
        ordering = ["-period_start"]

    def __str__(self):
        return f"Actual {self.kpi} — {self.actual_value}"


# ═══════════════════════════════════════════════════
# 9️⃣ KPIAssignment
# ═══════════════════════════════════════════════════

class KPIAssignmentModel(TenantAwareModel):
    """مدل ORM — تخصیص KPI به سطح سازمانی."""

    class Status(models.TextChoices):
        ACTIVE = "active", _("فعال")
        INACTIVE = "inactive", _("غیرفعال")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    kpi = models.ForeignKey(
        KPIDefinitionModel, on_delete=models.CASCADE,
        related_name="assignments",
        verbose_name=_("شاخص"),
    )

    level = models.CharField(_("سطح"), max_length=50)  # portfolio/program/project/org_unit/department/team
    entity_id = models.UUIDField(_("شناسه موجودیت"), null=True, blank=True)

    weight = models.DecimalField(
        _("وزن"), max_digits=5, decimal_places=2, default=1.0,
    )
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.ACTIVE,
    )

    notes = models.TextField(_("یادداشت"), blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_kpi_assignment"
        verbose_name = _("تخصیص KPI")
        verbose_name_plural = _("تخصیص‌های KPI")
        ordering = ["level", "-created_at"]

    def __str__(self):
        return f"{self.kpi} → {self.level} ({self.entity_id})"


# ═══════════════════════════════════════════════════
# 🔟 StrategyMap
# ═══════════════════════════════════════════════════

class StrategyMapModel(TenantAwareModel):
    """مدل ORM — نقشه راهبردی."""

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        PUBLISHED = "published", _("منتشرشده")
        ARCHIVED = "archived", _("بایگانی")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("نام"), max_length=500)
    description = models.TextField(_("توضیحات"), blank=True)
    version = models.PositiveIntegerField(_("نسخه"), default=1)

    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT,
    )

    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_strategy_map"
        verbose_name = _("نقشه راهبردی")
        verbose_name_plural = _("نقشه‌های راهبردی")
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.name} (v{self.version})"


# ═══════════════════════════════════════════════════
# 1️⃣1️⃣ StrategyMapPerspective
# ═══════════════════════════════════════════════════

class StrategyMapPerspectiveModel(TenantAwareModel):
    """مدل ORM — دیدگاه نقشه راهبردی."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    strategy_map = models.ForeignKey(
        StrategyMapModel, on_delete=models.CASCADE,
        related_name="perspectives",
        verbose_name=_("نقشه راهبردی"),
    )

    name = models.CharField(_("نام"), max_length=300)
    description = models.TextField(_("توضیحات"), blank=True)
    sort_order = models.PositiveIntegerField(_("ترتیب"), default=0)
    color = models.CharField(_("رنگ"), max_length=20, blank=True)

    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_map_perspective"
        verbose_name = _("دیدگاه نقشه")
        verbose_name_plural = _("دیدگاه‌های نقشه")
        ordering = ["sort_order"]

    def __str__(self):
        return self.name


# ═══════════════════════════════════════════════════
# 1️⃣2️⃣ StrategyMapObjective
# ═══════════════════════════════════════════════════

class StrategyMapObjectiveModel(TenantAwareModel):
    """مدل ORM — هدف روی نقشه راهبردی (گره)."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    strategy_map = models.ForeignKey(
        StrategyMapModel, on_delete=models.CASCADE,
        related_name="map_objectives",
        verbose_name=_("نقشه راهبردی"),
    )
    perspective = models.ForeignKey(
        StrategyMapPerspectiveModel, on_delete=models.CASCADE,
        related_name="map_objectives",
        verbose_name=_("دیدگاه"),
    )
    objective = models.ForeignKey(
        ObjectiveModel, on_delete=models.CASCADE,
        related_name="map_placements",
        verbose_name=_("هدف"),
    )

    x_position = models.FloatField(_("موقعیت X"), default=0)
    y_position = models.FloatField(_("موقعیت Y"), default=0)

    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_map_objective"
        verbose_name = _("هدف روی نقشه")
        verbose_name_plural = _("اهداف روی نقشه")

    def __str__(self):
        return f"{self.objective} @ ({self.x_position}, {self.y_position})"


# ═══════════════════════════════════════════════════
# 1️⃣3️⃣ CausalLink
# ═══════════════════════════════════════════════════

class CausalLinkModel(TenantAwareModel):
    """مدل ORM — ارتباط علّی بین اهداف."""

    class Strength(models.TextChoices):
        WEAK = "weak", _("ضعیف")
        MEDIUM = "medium", _("متوسط")
        STRONG = "strong", _("قوی")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    strategy_map = models.ForeignKey(
        StrategyMapModel, on_delete=models.CASCADE,
        related_name="causal_links",
        verbose_name=_("نقشه راهبردی"),
    )
    from_objective = models.ForeignKey(
        StrategyMapObjectiveModel, on_delete=models.CASCADE,
        related_name="outgoing_links",
        verbose_name=_("از هدف"),
    )
    to_objective = models.ForeignKey(
        StrategyMapObjectiveModel, on_delete=models.CASCADE,
        related_name="incoming_links",
        verbose_name=_("به هدف"),
    )

    strength = models.CharField(
        _("قدرت"), max_length=10,
        choices=Strength.choices, default=Strength.MEDIUM,
    )
    description = models.TextField(_("توضیحات"), blank=True)

    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_causal_link"
        verbose_name = _("ارتباط علّی")
        verbose_name_plural = _("ارتباطات علّی")

    def __str__(self):
        return f"{self.from_objective} → {self.to_objective} ({self.strength})"


# ═══════════════════════════════════════════════════
# 1️⃣4️⃣ Scorecard
# ═══════════════════════════════════════════════════

class ScorecardModel(TenantAwareModel):
    """مدل ORM — کارت امتیازی متوازن."""

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        ACTIVE = "active", _("فعال")
        CLOSED = "closed", _("بسته‌شده")
        ARCHIVED = "archived", _("بایگانی")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("نام"), max_length=500)
    description = models.TextField(_("توضیحات"), blank=True)

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="owned_scorecards",
        verbose_name=_("مالک"),
    )

    period_start = models.DateField(_("شروع دوره"), null=True, blank=True)
    period_end = models.DateField(_("پایان دوره"), null=True, blank=True)

    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT,
    )

    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_scorecard"
        verbose_name = _("کارت امتیازی")
        verbose_name_plural = _("کارت‌های امتیازی")
        ordering = ["-created_at"]

    def __str__(self):
        return self.name


# ═══════════════════════════════════════════════════
# 1️⃣5️⃣ ScorecardPerspective
# ═══════════════════════════════════════════════════

class ScorecardPerspectiveModel(TenantAwareModel):
    """مدل ORM — دیدگاه کارت امتیازی."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    scorecard = models.ForeignKey(
        ScorecardModel, on_delete=models.CASCADE,
        related_name="sc_perspectives",
        verbose_name=_("کارت امتیازی"),
    )

    name = models.CharField(_("نام"), max_length=300)
    weight = models.DecimalField(
        _("وزن"), max_digits=5, decimal_places=2, default=1.0,
    )
    sort_order = models.PositiveIntegerField(_("ترتیب"), default=0)

    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_sc_perspective"
        verbose_name = _("دیدگاه کارت امتیازی")
        verbose_name_plural = _("دیدگاه‌های کارت امتیازی")
        ordering = ["sort_order"]

    def __str__(self):
        return f"{self.scorecard} — {self.name}"


# ═══════════════════════════════════════════════════
# 1️⃣6️⃣ ScorecardMeasure
# ═══════════════════════════════════════════════════

class ScorecardMeasureModel(TenantAwareModel):
    """مدل ORM — سنجه کارت امتیازی."""

    class MeasureStatus(models.TextChoices):
        PENDING = "pending", _("در انتظار")
        ON_TRACK = "on_track", _("در مسیر")
        AT_RISK = "at_risk", _("در خطر")
        BEHIND = "behind", _("عقب‌مانده")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    perspective = models.ForeignKey(
        ScorecardPerspectiveModel, on_delete=models.CASCADE,
        related_name="measures",
        verbose_name=_("دیدگاه"),
    )
    kpi_assignment = models.ForeignKey(
        KPIAssignmentModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="scorecard_measures",
        verbose_name=_("تخصیص KPI"),
    )

    weight = models.DecimalField(
        _("وزن"), max_digits=5, decimal_places=2, default=1.0,
    )
    target_value = models.DecimalField(
        _("هدف"), max_digits=15, decimal_places=2, default=0,
    )
    actual_value = models.DecimalField(
        _("واقعی"), max_digits=15, decimal_places=2, default=0,
    )
    score = models.DecimalField(
        _("امتیاز"), max_digits=7, decimal_places=2, default=0,
    )
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=MeasureStatus.choices, default=MeasureStatus.PENDING,
    )

    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_sc_measure"
        verbose_name = _("سنجه کارت امتیازی")
        verbose_name_plural = _("سنجه‌های کارت امتیازی")

    def __str__(self):
        return f"{self.perspective} — {self.target_value} / {self.actual_value}"


# ═══════════════════════════════════════════════════
# Stage-Gate Governance Models
# ═══════════════════════════════════════════════════

class GateProcessModel(TenantAwareModel):
    """مدل ORM — فرآیند Stage-Gate."""

    class ApplicableTo(models.TextChoices):
        PROJECT = "project", _("پروژه")
        PROGRAM = "program", _("برنامه")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("نام"), max_length=255)
    description = models.TextField(_("توضیحات"), blank=True, default="")
    applicable_to = models.CharField(
        _("قابل اعمال برای"), max_length=20,
        choices=ApplicableTo.choices, default=ApplicableTo.PROJECT,
    )
    is_active = models.BooleanField(_("فعال"), default=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_gate_process"
        verbose_name = _("فرآیند Stage-Gate")
        verbose_name_plural = _("فرآیندهای Stage-Gate")

    def __str__(self):
        return self.name


class GateModel(TenantAwareModel):
    """مدل ORM — دروازه (مرحله در فرآیند Stage-Gate)."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    process = models.ForeignKey(
        GateProcessModel, on_delete=models.CASCADE,
        related_name="gates", verbose_name=_("فرآیند"),
    )
    name = models.CharField(_("نام"), max_length=255)
    sequence = models.PositiveIntegerField(_("ترتیب"), default=0)
    description = models.TextField(_("توضیحات"), blank=True, default="")
    mandatory_deliverables = models.JSONField(
        _("تحویل‌دادنی‌های اجباری"), default=list, blank=True,
    )
    criteria = models.TextField(_("معیارها"), blank=True, default="")
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_gate"
        verbose_name = _("دروازه")
        verbose_name_plural = _("دروازه‌ها")
        ordering = ["sequence"]

    def __str__(self):
        return f"{self.process.name} — {self.name}"


class GateReviewModel(TenantAwareModel):
    """مدل ORM — بازبینی دروازه."""

    class ReviewStatus(models.TextChoices):
        PENDING = "pending", _("در انتظار")
        IN_REVIEW = "in_review", _("در حال بررسی")
        PASSED = "passed", _("تأیید شده")
        CONDITIONAL = "conditional", _("مشروط")
        FAILED = "failed", _("رد شده")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    gate = models.ForeignKey(
        GateModel, on_delete=models.CASCADE,
        related_name="reviews", verbose_name=_("دروازه"),
    )
    entity_id = models.UUIDField(_("شناسه موجودیت"))
    entity_type = models.CharField(_("نوع موجودیت"), max_length=50, default="project")
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=ReviewStatus.choices, default=ReviewStatus.PENDING,
    )
    review_date = models.DateField(_("تاریخ بازبینی"), null=True, blank=True)
    notes = models.TextField(_("یادداشت‌ها"), blank=True, default="")
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_gate_review"
        verbose_name = _("بازبینی دروازه")
        verbose_name_plural = _("بازبینی‌های دروازه")

    def __str__(self):
        return f"{self.gate} — {self.status}"


class GateReviewerModel(TenantAwareModel):
    """مدل ORM — بازبین دروازه."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    review = models.ForeignKey(
        GateReviewModel, on_delete=models.CASCADE,
        related_name="reviewers", verbose_name=_("بازبینی"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
        related_name="gate_reviewer_assignments",
        verbose_name=_("کاربر"),
    )
    role = models.CharField(_("نقش"), max_length=50, blank=True, default="")
    decision = models.CharField(_("تصمیم"), max_length=20, blank=True, default="pending")
    comments = models.TextField(_("نظرات"), blank=True, default="")
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_gate_reviewer"
        verbose_name = _("بازبین دروازه")
        verbose_name_plural = _("بازبینان دروازه")

    def __str__(self):
        return f"{self.review} — {self.user}"


class GateDeliverableModel(TenantAwareModel):
    """مدل ORM — تحویل‌دادنی دروازه."""

    class DeliverableStatus(models.TextChoices):
        PENDING = "pending", _("در انتظار")
        SUBMITTED = "submitted", _("ارسال‌شده")
        ACCEPTED = "accepted", _("پذیرفته‌شده")
        REJECTED = "rejected", _("ردشده")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    review = models.ForeignKey(
        GateReviewModel, on_delete=models.CASCADE,
        related_name="deliverables", verbose_name=_("بازبینی"),
    )
    name = models.CharField(_("نام"), max_length=255)
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=DeliverableStatus.choices, default=DeliverableStatus.PENDING,
    )
    document_id = models.UUIDField(
        _("شناسه سند"), null=True, blank=True,
        help_text=_("ارجاع به سند در ماژول مدیریت اسناد"),
    )
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_gate_deliverable"
        verbose_name = _("تحویل‌دادنی دروازه")
        verbose_name_plural = _("تحویل‌دادنی‌های دروازه")

    def __str__(self):
        return f"{self.review} — {self.name}"


# ═══════════════════════════════════════════════════
# Corporate Policy Management Models
# ═══════════════════════════════════════════════════

class PolicyModel(TenantAwareModel):
    """مدل ORM — سیاست سازمانی."""

    class PolicyStatus(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        ACTIVE = "active", _("فعال")
        UNDER_REVIEW = "under_review", _("در حال بازنگری")
        RETIRED = "retired", _("بازنشسته")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(_("عنوان"), max_length=255)
    code = models.CharField(_("کد"), max_length=50, blank=True, default="")
    category = models.CharField(_("دسته‌بندی"), max_length=100, blank=True, default="")
    content = models.TextField(_("محتوا"), blank=True, default="")
    version = models.PositiveIntegerField(_("نسخه"), default=1)
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=PolicyStatus.choices, default=PolicyStatus.DRAFT,
    )
    effective_date = models.DateField(_("تاریخ اجرا"), null=True, blank=True)
    review_date = models.DateField(_("تاریخ بازنگری"), null=True, blank=True)
    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="owned_policies",
        verbose_name=_("مالک"),
    )
    approver = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="approved_policies",
        verbose_name=_("تأییدکننده"),
    )
    document_id = models.UUIDField(
        _("شناسه سند"), null=True, blank=True,
        help_text=_("ارجاع به ماژول مدیریت اسناد"),
    )
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_policy"
        verbose_name = _("سیاست سازمانی")
        verbose_name_plural = _("سیاست‌های سازمانی")

    def __str__(self):
        return f"{self.code} — {self.title}"


class PolicyAcknowledgmentModel(TenantAwareModel):
    """مدل ORM — تأیید آشنایی با سیاست."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    policy = models.ForeignKey(
        PolicyModel, on_delete=models.CASCADE,
        related_name="acknowledgments", verbose_name=_("سیاست"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
        related_name="policy_acknowledgments",
        verbose_name=_("کاربر"),
    )
    acknowledged_at = models.DateTimeField(_("تاریخ تأیید"), null=True, blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_policy_ack"
        verbose_name = _("تأیید آشنایی سیاست")
        verbose_name_plural = _("تأییدهای آشنایی سیاست")
        unique_together = [("policy", "user")]

    def __str__(self):
        return f"{self.policy} — {self.user}"


# ═══════════════════════════════════════════════════
# 🔗 Cross-Module Alignment
# ═══════════════════════════════════════════════════

class ObjectivePortfolioAlignmentModel(TenantAwareModel):
    """ارتباط Objective ↔ Portfolio (cross-module alignment)."""

    class AlignmentLevel(models.TextChoices):
        PRIMARY = "primary", _("اصلی")
        SECONDARY = "secondary", _("فرعی")
        SUPPORTING = "supporting", _("پشتیبان")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    objective = models.ForeignKey(
        ObjectiveModel, on_delete=models.CASCADE,
        related_name="portfolio_alignments", verbose_name=_("هدف"),
    )
    portfolio_id = models.UUIDField(_("شناسه پورتفولیو"))
    alignment_level = models.CharField(
        _("سطح همراستایی"), max_length=20,
        choices=AlignmentLevel.choices, default=AlignmentLevel.PRIMARY,
    )
    strategic_fit_score = models.DecimalField(
        _("امتیاز تناسب استراتژیک"), max_digits=5, decimal_places=2,
        default=0,
    )
    weight = models.DecimalField(
        _("وزن"), max_digits=5, decimal_places=2, default=1.0,
    )
    notes = models.TextField(_("یادداشت"), blank=True)
    is_active = models.BooleanField(_("فعال"), default=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "strategy"
        db_table = "str_objective_portfolio_alignment"
        verbose_name = _("همراستایی هدف-پورتفولیو")
        verbose_name_plural = _("همراستایی‌های هدف-پورتفولیو")
        unique_together = [("objective", "portfolio_id")]

    def __str__(self):
        return f"{self.objective} → Portfolio({self.portfolio_id})"
