"""
PM ORM Models — Infrastructure Layer.

مدل‌های Django ORM ماژول مدیریت پروژه.
تمام جداول با پیشوند pm_ هستند.
verbose_nameها به فارسی.
"""
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️⃣ Project
# ═══════════════════════════════════════════════════

class ProjectModel(TenantAwareModel):
    """مدل ORM — پروژه."""

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        PLANNING = "planning", _("در حال برنامه‌ریزی")
        ACTIVE = "active", _("فعال")
        ON_HOLD = "on_hold", _("متوقف")
        COMPLETED = "completed", _("تکمیل‌شده")
        CANCELLED = "cancelled", _("لغوشده")
        ARCHIVED = "archived", _("آرشیوشده")

    class Priority(models.TextChoices):
        CRITICAL = "critical", _("بحرانی")
        HIGH = "high", _("بالا")
        MEDIUM = "medium", _("متوسط")
        LOW = "low", _("پایین")

    class ProjectType(models.TextChoices):
        PORTFOLIO = "portfolio", _("پورتفولیو")
        PROGRAM = "program", _("برنامه")
        PROJECT = "project", _("پروژه")
        SUB_PROJECT = "sub_project", _("زیرپروژه")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    code = models.CharField(_("کد پروژه"), max_length=50, db_index=True)
    title = models.CharField(_("عنوان"), max_length=500)
    description = models.TextField(_("توضیحات"), blank=True)

    project_type = models.CharField(
        _("نوع"), max_length=20,
        choices=ProjectType.choices, default=ProjectType.PROJECT,
    )
    parent = models.ForeignKey(
        "self", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="children",
        verbose_name=_("پروژه مادر"),
    )

    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT, db_index=True,
    )
    priority = models.CharField(
        _("اولویت"), max_length=20,
        choices=Priority.choices, default=Priority.MEDIUM,
    )

    # --- Dates ---
    planned_start = models.DateField(_("شروع برنامه‌ای"), null=True, blank=True)
    planned_end = models.DateField(_("پایان برنامه‌ای"), null=True, blank=True)
    actual_start = models.DateField(_("شروع واقعی"), null=True, blank=True)
    actual_end = models.DateField(_("پایان واقعی"), null=True, blank=True)

    # --- Progress ---
    progress = models.PositiveSmallIntegerField(_("درصد پیشرفت"), default=0)

    # --- Budget & Cost ---
    total_budget = models.DecimalField(
        _("بودجه کل"), max_digits=18, decimal_places=0, default=0,
    )
    actual_cost = models.DecimalField(
        _("هزینه واقعی"), max_digits=18, decimal_places=0, default=0,
    )
    estimated_cost = models.DecimalField(
        _("هزینه تخمینی"), max_digits=18, decimal_places=0, default=0,
    )

    # --- Integration: Platform FKs ---
    company = models.ForeignKey(
        "core_organization.Company", on_delete=models.PROTECT,
        null=True, blank=True, related_name="pm_projects",
        verbose_name=_("شرکت"),
    )
    org_unit = models.ForeignKey(
        "core_organization.OrganizationalUnit", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_projects",
        verbose_name=_("واحد سازمانی"),
    )
    currency = models.ForeignKey(
        "core_currency.Currency", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_projects",
        verbose_name=_("واحد پول"),
    )
    manager = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="managed_projects",
        verbose_name=_("مدیر پروژه"),
    )

    # --- Calendar & Settings ---
    calendar = models.ForeignKey(
        "pm.CalendarModel", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="projects",
        verbose_name=_("تقویم"),
    )
    color = models.CharField(_("رنگ"), max_length=20, default="#3B82F6")
    tags = models.JSONField(_("برچسب‌ها"), default=list, blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    # --- Audit ---
    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="created_pm_projects",
        verbose_name=_("ایجادکننده"),
    )
    updated_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="updated_pm_projects",
        verbose_name=_("بروزرسان"),
    )

    class Meta:
        app_label = "pm"
        db_table = "pm_project"
        verbose_name = _("پروژه")
        verbose_name_plural = _("پروژه‌ها")
        ordering = ["-created_at"]
        unique_together = [("tenant", "code")]

    def __str__(self):
        return f"{self.code} — {self.title}"


# ═══════════════════════════════════════════════════
# 2️⃣ Task
# ═══════════════════════════════════════════════════

class TaskModel(TenantAwareModel):
    """مدل ORM — تسک پروژه."""

    class Status(models.TextChoices):
        NOT_STARTED = "not_started", _("شروع نشده")
        READY = "ready", _("آماده")
        IN_PROGRESS = "in_progress", _("در حال انجام")
        COMPLETED = "completed", _("تکمیل‌شده")
        ON_HOLD = "on_hold", _("متوقف")
        CANCELLED = "cancelled", _("لغوشده")

    class TaskType(models.TextChoices):
        TASK = "task", _("تسک")
        MILESTONE = "milestone", _("نقطه عطف")
        SUMMARY = "summary", _("تسک خلاصه")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="tasks", verbose_name=_("پروژه"),
    )
    code = models.CharField(_("کد WBS"), max_length=50, blank=True, db_index=True)
    title = models.CharField(_("عنوان"), max_length=500)
    description = models.TextField(_("توضیحات"), blank=True)

    parent = models.ForeignKey(
        "self", on_delete=models.CASCADE,
        null=True, blank=True, related_name="children",
        verbose_name=_("تسک والد"),
    )
    sort_order = models.IntegerField(_("ترتیب"), default=0, db_index=True)

    task_type = models.CharField(
        _("نوع"), max_length=20,
        choices=TaskType.choices, default=TaskType.TASK,
    )
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.NOT_STARTED, db_index=True,
    )

    # --- Dates ---
    planned_start = models.DateField(_("شروع برنامه‌ای"), null=True, blank=True)
    planned_end = models.DateField(_("پایان برنامه‌ای"), null=True, blank=True)
    actual_start = models.DateField(_("شروع واقعی"), null=True, blank=True)
    actual_end = models.DateField(_("پایان واقعی"), null=True, blank=True)
    duration = models.PositiveIntegerField(_("مدت (روز)"), default=1)

    # --- Progress ---
    progress = models.PositiveSmallIntegerField(_("درصد پیشرفت"), default=0)

    # --- Cost ---
    planned_cost = models.DecimalField(
        _("هزینه برنامه‌ای"), max_digits=18, decimal_places=0, default=0,
    )
    actual_cost = models.DecimalField(
        _("هزینه واقعی"), max_digits=18, decimal_places=0, default=0,
    )

    # --- Critical Path ---
    is_critical = models.BooleanField(_("مسیر بحرانی"), default=False)
    is_milestone = models.BooleanField(_("نقطه عطف"), default=False)
    early_start = models.DateField(_("ES"), null=True, blank=True)
    early_finish = models.DateField(_("EF"), null=True, blank=True)
    late_start = models.DateField(_("LS"), null=True, blank=True)
    late_finish = models.DateField(_("LF"), null=True, blank=True)
    total_float = models.IntegerField(_("شناوری کل"), null=True, blank=True)
    free_float = models.IntegerField(_("شناوری آزاد"), null=True, blank=True)

    # --- Assignment ---
    assignee = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_assigned_tasks",
        verbose_name=_("مسئول"),
    )

    # --- Assignment Policy ---
    class AssignmentPolicy(models.TextChoices):
        MANUAL = "manual", _("دستی")
        AUTO_LEAST_LOAD = "auto_least_load", _("خودکار — کمترین بار")
        AUTO_ROUND_ROBIN = "auto_round_robin", _("خودکار — چرخشی")
        SELF_CLAIM = "self_claim", _("انتخاب توسط اعضا")

    assignment_policy = models.CharField(
        _("سیاست تخصیص"), max_length=30,
        choices=AssignmentPolicy.choices, default=AssignmentPolicy.MANUAL,
    )

    # --- Scheduling Mode & Constraints ---
    class SchedulingMode(models.TextChoices):
        AUTO = "auto", _("خودکار")
        MANUAL = "manual", _("دستی")

    class DurationType(models.TextChoices):
        FIXED_DURATION = "fixed_duration", _("مدت ثابت")
        FIXED_UNITS = "fixed_units", _("واحد ثابت")
        FIXED_WORK = "fixed_work", _("کار ثابت")

    class PercentCompleteType(models.TextChoices):
        PHYSICAL = "physical", _("فیزیکی")
        DURATION = "duration", _("مدت")
        WORK = "work", _("کار")

    class ConstraintType(models.TextChoices):
        ASAP = "asap", _("در اولین فرصت")
        ALAP = "alap", _("در آخرین فرصت")
        MUST_START_ON = "must_start_on", _("باید شروع شود در")
        MUST_FINISH_ON = "must_finish_on", _("باید تمام شود در")
        START_NO_EARLIER_THAN = "start_no_earlier_than", _("شروع نه زودتر از")
        START_NO_LATER_THAN = "start_no_later_than", _("شروع نه دیرتر از")
        FINISH_NO_EARLIER_THAN = "finish_no_earlier_than", _("پایان نه زودتر از")
        FINISH_NO_LATER_THAN = "finish_no_later_than", _("پایان نه دیرتر از")

    scheduling_mode = models.CharField(
        _("حالت زمان‌بندی"), max_length=20,
        choices=SchedulingMode.choices, default=SchedulingMode.AUTO,
    )
    duration_type = models.CharField(
        _("نوع مدت"), max_length=20,
        choices=DurationType.choices, default=DurationType.FIXED_DURATION,
    )
    percent_complete_type = models.CharField(
        _("نوع درصد تکمیل"), max_length=20,
        choices=PercentCompleteType.choices, default=PercentCompleteType.PHYSICAL,
    )
    remaining_duration = models.PositiveIntegerField(
        _("مدت باقیمانده (روز)"), null=True, blank=True,
    )
    constraint_type = models.CharField(
        _("نوع محدودیت"), max_length=30,
        choices=ConstraintType.choices, default=ConstraintType.ASAP,
    )
    constraint_date = models.DateField(_("تاریخ محدودیت"), null=True, blank=True)
    deadline = models.DateField(_("ددلاین"), null=True, blank=True)
    is_effort_driven = models.BooleanField(_("وابسته به تلاش"), default=False)

    # --- Calendar ---
    calendar = models.ForeignKey(
        "pm.CalendarModel", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="tasks",
        verbose_name=_("تقویم"),
    )

    # --- Metadata ---
    color = models.CharField(_("رنگ"), max_length=20, blank=True)
    tags = models.JSONField(_("برچسب‌ها"), default=list, blank=True)
    notes = models.TextField(_("یادداشت"), blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    # --- Audit ---
    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_task"
        verbose_name = _("تسک")
        verbose_name_plural = _("تسک‌ها")
        ordering = ["sort_order", "created_at"]

    def __str__(self):
        return f"{self.code} — {self.title}"


# ═══════════════════════════════════════════════════
# 3️⃣ Dependency
# ═══════════════════════════════════════════════════

class DependencyModel(TenantAwareModel):
    """مدل ORM — وابستگی بین تسک‌ها."""

    class DependencyType(models.TextChoices):
        FS = "FS", _("پایان به شروع")
        SS = "SS", _("شروع به شروع")
        FF = "FF", _("پایان به پایان")
        SF = "SF", _("شروع به پایان")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="dependencies", verbose_name=_("پروژه"),
    )
    predecessor = models.ForeignKey(
        TaskModel, on_delete=models.CASCADE,
        related_name="successor_dependencies", verbose_name=_("پیشنیاز"),
    )
    successor = models.ForeignKey(
        TaskModel, on_delete=models.CASCADE,
        related_name="predecessor_dependencies", verbose_name=_("جانشین"),
    )
    dependency_type = models.CharField(
        _("نوع وابستگی"), max_length=2,
        choices=DependencyType.choices, default=DependencyType.FS,
    )
    lag_days = models.IntegerField(_("تأخیر/تقدم (روز)"), default=0)

    # --- Audit ---
    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_dependency"
        verbose_name = _("وابستگی")
        verbose_name_plural = _("وابستگی‌ها")
        unique_together = [("predecessor", "successor")]

    def __str__(self):
        return f"{self.predecessor} → {self.successor} ({self.dependency_type})"


# ═══════════════════════════════════════════════════
# 3️⃣.5 Task Assignment (Hybrid Assignment)
# ═══════════════════════════════════════════════════

class TaskAssignmentModel(TenantAwareModel):
    """مدل ORM — تخصیص کاربر به تسک (سیستم Hybrid Assignment)."""

    class AssignmentRole(models.TextChoices):
        PRIMARY = "primary", _("مسئول اصلی")
        SECONDARY = "secondary", _("مسئول فرعی")
        REVIEWER = "reviewer", _("بازبین")
        OBSERVER = "observer", _("ناظر")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    task = models.ForeignKey(
        TaskModel, on_delete=models.CASCADE,
        related_name="task_assignments", verbose_name=_("تسک"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
        null=True, blank=True,
        related_name="pm_task_assignments", verbose_name=_("کاربر"),
    )
    role_id = models.UUIDField(
        _("شناسه نقش"), null=True, blank=True,
        help_text=_("UUID مرجع به Role سیستم"),
    )
    assignment_role = models.CharField(
        _("نقش تخصیص"), max_length=20,
        choices=AssignmentRole.choices, default=AssignmentRole.PRIMARY,
    )
    is_active = models.BooleanField(_("فعال"), default=True)
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_task_assignment"
        verbose_name = _("تخصیص تسک")
        verbose_name_plural = _("تخصیص‌های تسک")
        unique_together = [("task", "user", "assignment_role")]

    def __str__(self):
        return f"{self.user} → {self.task} ({self.get_assignment_role_display()})"


# ═══════════════════════════════════════════════════
# 4️⃣ Resource
# ═══════════════════════════════════════════════════

class ResourceModel(TenantAwareModel):
    """مدل ORM — منبع پروژه."""

    class ResourceType(models.TextChoices):
        HUMAN = "human", _("انسانی")
        EQUIPMENT = "equipment", _("تجهیزات")
        MATERIAL = "material", _("مواد")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("نام"), max_length=255)
    code = models.CharField(_("کد"), max_length=50, blank=True, db_index=True)
    resource_type = models.CharField(
        _("نوع"), max_length=20,
        choices=ResourceType.choices, default=ResourceType.HUMAN,
    )

    # --- Integration ---
    employee_id = models.UUIDField(
        _("شناسه کارمند"), null=True, blank=True, db_index=True,
        help_text=_("UUID مرجع به Employee ماژول HRM"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_resources",
        verbose_name=_("کاربر"),
    )
    company = models.ForeignKey(
        "core_organization.Company", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_resources",
        verbose_name=_("شرکت"),
    )

    # --- Rates ---
    standard_rate = models.DecimalField(
        _("نرخ استاندارد"), max_digits=18, decimal_places=0, default=0,
    )
    overtime_rate = models.DecimalField(
        _("نرخ اضافه‌کاری"), max_digits=18, decimal_places=0, default=0,
    )
    cost_per_use = models.DecimalField(
        _("هزینه هر بار استفاده"), max_digits=18, decimal_places=0, default=0,
    )
    currency = models.ForeignKey(
        "core_currency.Currency", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_resources",
        verbose_name=_("واحد پول"),
    )

    # --- Capacity ---
    max_units = models.DecimalField(
        _("حداکثر واحد (%)"), max_digits=5, decimal_places=2, default=100,
    )
    calendar = models.ForeignKey(
        "pm.CalendarModel", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="resources",
        verbose_name=_("تقویم"),
    )

    # --- Contact ---
    email = models.EmailField(_("ایمیل"), blank=True)
    phone = models.CharField(_("تلفن"), max_length=50, blank=True)

    # --- Status ---
    is_active = models.BooleanField(_("فعال"), default=True)
    notes = models.TextField(_("یادداشت"), blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    # --- Audit ---
    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_resource"
        verbose_name = _("منبع")
        verbose_name_plural = _("منابع")
        unique_together = [("tenant", "code")]

    def __str__(self):
        return f"{self.name} ({self.get_resource_type_display()})"


# ═══════════════════════════════════════════════════
# 5️⃣ Resource Assignment
# ═══════════════════════════════════════════════════

class ResourceAssignmentModel(TenantAwareModel):
    """مدل ORM — تخصیص منبع به تسک."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="resource_assignments", verbose_name=_("پروژه"),
    )
    task = models.ForeignKey(
        TaskModel, on_delete=models.CASCADE,
        related_name="resource_assignments", verbose_name=_("تسک"),
    )
    resource = models.ForeignKey(
        ResourceModel, on_delete=models.CASCADE,
        related_name="assignments", verbose_name=_("منبع"),
    )

    units = models.DecimalField(
        _("واحد (%)"), max_digits=5, decimal_places=2, default=100,
    )
    planned_hours = models.DecimalField(
        _("ساعت برنامه‌ای"), max_digits=10, decimal_places=2, default=0,
    )
    actual_hours = models.DecimalField(
        _("ساعت واقعی"), max_digits=10, decimal_places=2, default=0,
    )
    planned_cost = models.DecimalField(
        _("هزینه برنامه‌ای"), max_digits=18, decimal_places=0, default=0,
    )
    actual_cost = models.DecimalField(
        _("هزینه واقعی"), max_digits=18, decimal_places=0, default=0,
    )

    start_date = models.DateField(_("تاریخ شروع"), null=True, blank=True)
    end_date = models.DateField(_("تاریخ پایان"), null=True, blank=True)
    is_active = models.BooleanField(_("فعال"), default=True)
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_resource_assignment"
        verbose_name = _("تخصیص منبع")
        verbose_name_plural = _("تخصیص‌های منبع")
        unique_together = [("task", "resource")]

    def __str__(self):
        return f"{self.resource} → {self.task}"


# ═══════════════════════════════════════════════════
# 6️⃣ Budget
# ═══════════════════════════════════════════════════

class BudgetModel(TenantAwareModel):
    """مدل ORM — بودجه."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="budgets", verbose_name=_("پروژه"),
    )
    task = models.ForeignKey(
        TaskModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="budgets",
        verbose_name=_("تسک (WBS)"),
    )

    name = models.CharField(_("نام بودجه"), max_length=255)
    description = models.TextField(_("توضیحات"), blank=True)

    original_budget = models.DecimalField(
        _("بودجه اولیه"), max_digits=18, decimal_places=0, default=0,
    )
    revised_budget = models.DecimalField(
        _("بودجه تجدیدنظرشده"), max_digits=18, decimal_places=0, default=0,
    )
    committed_cost = models.DecimalField(
        _("هزینه تعهدشده"), max_digits=18, decimal_places=0, default=0,
    )
    actual_cost = models.DecimalField(
        _("هزینه واقعی"), max_digits=18, decimal_places=0, default=0,
    )

    currency = models.ForeignKey(
        "core_currency.Currency", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_budgets",
        verbose_name=_("واحد پول"),
    )

    period_start = models.DateField(_("شروع دوره"), null=True, blank=True)
    period_end = models.DateField(_("پایان دوره"), null=True, blank=True)
    is_active = models.BooleanField(_("فعال"), default=True)
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_budget"
        verbose_name = _("بودجه")
        verbose_name_plural = _("بودجه‌ها")

    def __str__(self):
        return f"{self.name} — {self.project}"


# ═══════════════════════════════════════════════════
# 7️⃣ Cost Entry
# ═══════════════════════════════════════════════════

class CostEntryModel(TenantAwareModel):
    """مدل ORM — ثبت هزینه واقعی."""

    class CostType(models.TextChoices):
        FIXED = "fixed", _("ثابت")
        VARIABLE = "variable", _("متغیر")
        OVERHEAD = "overhead", _("سربار")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="cost_entries", verbose_name=_("پروژه"),
    )
    task = models.ForeignKey(
        TaskModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="cost_entries",
        verbose_name=_("تسک"),
    )
    resource = models.ForeignKey(
        ResourceModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="cost_entries",
        verbose_name=_("منبع"),
    )
    budget = models.ForeignKey(
        BudgetModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="cost_entries",
        verbose_name=_("بودجه"),
    )

    description = models.CharField(_("شرح"), max_length=500)
    amount = models.DecimalField(
        _("مبلغ"), max_digits=18, decimal_places=0, default=0,
    )
    cost_type = models.CharField(
        _("نوع هزینه"), max_length=20,
        choices=CostType.choices, default=CostType.VARIABLE,
    )
    currency = models.ForeignKey(
        "core_currency.Currency", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_cost_entries",
        verbose_name=_("واحد پول"),
    )
    entry_date = models.DateField(_("تاریخ ثبت"), null=True, blank=True)
    reference_number = models.CharField(_("شماره مرجع"), max_length=100, blank=True)
    notes = models.TextField(_("یادداشت"), blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_cost_entries",
        verbose_name=_("ثبت‌کننده"),
    )

    class Meta:
        app_label = "pm"
        db_table = "pm_cost_entry"
        verbose_name = _("ثبت هزینه")
        verbose_name_plural = _("ثبت‌های هزینه")
        ordering = ["-entry_date"]

    def __str__(self):
        return f"{self.description} — {self.amount}"


# ═══════════════════════════════════════════════════
# 8️⃣ Risk
# ═══════════════════════════════════════════════════

class RiskModel(TenantAwareModel):
    """مدل ORM — ریسک پروژه."""

    class Probability(models.TextChoices):
        VERY_LOW = "very_low", _("بسیار کم")
        LOW = "low", _("کم")
        MEDIUM = "medium", _("متوسط")
        HIGH = "high", _("زیاد")
        VERY_HIGH = "very_high", _("بسیار زیاد")

    class Impact(models.TextChoices):
        NEGLIGIBLE = "negligible", _("ناچیز")
        MINOR = "minor", _("جزئی")
        MODERATE = "moderate", _("متوسط")
        MAJOR = "major", _("عمده")
        CRITICAL = "critical", _("بحرانی")

    class Status(models.TextChoices):
        IDENTIFIED = "identified", _("شناسایی‌شده")
        ANALYZING = "analyzing", _("در حال تحلیل")
        PLANNED = "planned", _("برنامه‌ریزی‌شده")
        MITIGATING = "mitigating", _("در حال کاهش")
        MONITORING = "monitoring", _("نظارت")
        CLOSED = "closed", _("بسته‌شده")
        OCCURRED = "occurred", _("رخ‌داده")

    class ResponseStrategy(models.TextChoices):
        AVOID = "avoid", _("اجتناب")
        MITIGATE = "mitigate", _("کاهش")
        TRANSFER = "transfer", _("انتقال")
        ACCEPT = "accept", _("پذیرش")
        EXPLOIT = "exploit", _("بهره‌برداری")
        ENHANCE = "enhance", _("تقویت")
        SHARE = "share", _("اشتراک")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="risks", verbose_name=_("پروژه"),
    )

    code = models.CharField(_("کد ریسک"), max_length=50, blank=True, db_index=True)
    title = models.CharField(_("عنوان"), max_length=500)
    description = models.TextField(_("شرح"), blank=True)
    category = models.CharField(_("دسته‌بندی"), max_length=100, blank=True)

    probability = models.CharField(
        _("احتمال"), max_length=20,
        choices=Probability.choices, default=Probability.MEDIUM,
    )
    impact = models.CharField(
        _("تأثیر"), max_length=20,
        choices=Impact.choices, default=Impact.MODERATE,
    )
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.IDENTIFIED, db_index=True,
    )

    response_strategy = models.CharField(
        _("استراتژی پاسخ"), max_length=20,
        choices=ResponseStrategy.choices, default=ResponseStrategy.MITIGATE,
    )
    response_plan = models.TextField(_("برنامه پاسخ"), blank=True)
    mitigation_actions = models.TextField(_("اقدامات کاهشی"), blank=True)

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="owned_pm_risks",
        verbose_name=_("صاحب ریسک"),
    )

    cost_impact = models.DecimalField(
        _("تأثیر هزینه‌ای"), max_digits=18, decimal_places=0, default=0,
    )
    schedule_impact_days = models.IntegerField(_("تأثیر زمانی (روز)"), default=0)
    affected_tasks = models.JSONField(_("تسک‌های تأثیرپذیر"), default=list, blank=True)

    identified_date = models.DateField(_("تاریخ شناسایی"), null=True, blank=True)
    due_date = models.DateField(_("مهلت"), null=True, blank=True)
    closed_date = models.DateField(_("تاریخ بسته‌شدن"), 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 = "pm"
        db_table = "pm_risk"
        verbose_name = _("ریسک")
        verbose_name_plural = _("ریسک‌ها")
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.code} — {self.title}"

    @property
    def risk_score(self):
        """امتیاز ریسک = احتمال × تأثیر"""
        prob_weight = {"very_low": 1, "low": 2, "medium": 3, "high": 4, "very_high": 5}
        impact_weight = {"negligible": 1, "minor": 2, "moderate": 3, "major": 4, "critical": 5}
        return prob_weight.get(self.probability, 3) * impact_weight.get(self.impact, 3)


# ═══════════════════════════════════════════════════
# 9️⃣ Baseline
# ═══════════════════════════════════════════════════

class BaselineModel(TenantAwareModel):
    """مدل ORM — خط پایه."""

    class BaselineType(models.TextChoices):
        INITIAL = "initial", _("اولیه")
        REVISED = "revised", _("تجدیدنظرشده")
        CURRENT = "current", _("جاری")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="baselines", verbose_name=_("پروژه"),
    )

    name = models.CharField(_("نام"), max_length=255)
    description = models.TextField(_("توضیحات"), blank=True)
    baseline_type = models.CharField(
        _("نوع"), max_length=20,
        choices=BaselineType.choices, default=BaselineType.INITIAL,
    )
    is_active = models.BooleanField(_("فعال"), default=False)

    snapshot_date = models.DateField(_("تاریخ"), null=True, blank=True)
    snapshot_data = models.JSONField(_("داده‌های خط پایه"), default=dict, blank=True)

    total_tasks = models.PositiveIntegerField(_("تعداد تسک‌ها"), default=0)
    total_cost = models.DecimalField(
        _("هزینه کل"), max_digits=18, decimal_places=0, default=0,
    )
    planned_start = models.DateField(_("شروع برنامه‌ای"), null=True, blank=True)
    planned_end = models.DateField(_("پایان برنامه‌ای"), null=True, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_baselines",
        verbose_name=_("ایجادکننده"),
    )

    class Meta:
        app_label = "pm"
        db_table = "pm_baseline"
        verbose_name = _("خط پایه")
        verbose_name_plural = _("خطوط پایه")
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.name} — {self.project}"


# ═══════════════════════════════════════════════════
# 🔟 Calendar & Holiday
# ═══════════════════════════════════════════════════

class CalendarModel(TenantAwareModel):
    """مدل ORM — تقویم کاری."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("نام"), max_length=255)
    description = models.TextField(_("توضیحات"), blank=True)
    is_default = models.BooleanField(_("تقویم پیش‌فرض"), default=False)

    work_start = models.TimeField(_("شروع کار"), default="08:00")
    work_end = models.TimeField(_("پایان کار"), default="17:00")
    hours_per_day = models.PositiveSmallIntegerField(_("ساعت کاری در روز"), default=8)

    working_days = models.JSONField(
        _("روزهای کاری"), default=list, blank=True,
        help_text=_("لیست شماره روزها: 0=دوشنبه ... 6=یکشنبه"),
    )
    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 = "pm"
        db_table = "pm_calendar"
        verbose_name = _("تقویم")
        verbose_name_plural = _("تقویم‌ها")

    def __str__(self):
        return self.name


class HolidayModel(TenantAwareModel):
    """مدل ORM — تعطیلات."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    calendar = models.ForeignKey(
        CalendarModel, on_delete=models.CASCADE,
        related_name="holidays", verbose_name=_("تقویم"),
    )

    name = models.CharField(_("نام"), max_length=255)
    holiday_date = models.DateField(_("تاریخ"), db_index=True)
    is_recurring = models.BooleanField(_("تکرارشونده"), default=False)
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_holiday"
        verbose_name = _("تعطیلی")
        verbose_name_plural = _("تعطیلات")
        ordering = ["holiday_date"]
        unique_together = [("calendar", "holiday_date")]

    def __str__(self):
        return f"{self.name} — {self.holiday_date}"


# ═══════════════════════════════════════════════════
# 1️⃣1️⃣ Change Request
# ═══════════════════════════════════════════════════

class ChangeRequestModel(TenantAwareModel):
    """مدل ORM — درخواست تغییر."""

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        SUBMITTED = "submitted", _("ارسال‌شده")
        UNDER_REVIEW = "under_review", _("در حال بررسی")
        APPROVED = "approved", _("تأیید‌شده")
        REJECTED = "rejected", _("ردشده")
        IMPLEMENTED = "implemented", _("اجراشده")
        CLOSED = "closed", _("بسته‌شده")

    class Priority(models.TextChoices):
        CRITICAL = "critical", _("بحرانی")
        HIGH = "high", _("بالا")
        MEDIUM = "medium", _("متوسط")
        LOW = "low", _("پایین")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="change_requests", verbose_name=_("پروژه"),
    )

    code = models.CharField(_("کد"), max_length=50, blank=True, db_index=True)
    title = models.CharField(_("عنوان"), max_length=500)
    description = models.TextField(_("شرح"), blank=True)
    justification = models.TextField(_("توجیه"), blank=True)

    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT, db_index=True,
    )
    priority = models.CharField(
        _("اولویت"), max_length=20,
        choices=Priority.choices, default=Priority.MEDIUM,
    )

    scope_impact = models.TextField(_("تأثیر بر دامنه"), blank=True)
    cost_impact = models.DecimalField(
        _("تأثیر هزینه‌ای"), max_digits=18, decimal_places=0, default=0,
    )
    schedule_impact_days = models.IntegerField(_("تأثیر زمانی (روز)"), default=0)

    requester = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_change_requests_made",
        verbose_name=_("درخواست‌کننده"),
    )
    reviewer = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_change_requests_reviewed",
        verbose_name=_("بررسی‌کننده"),
    )

    workflow_instance_id = models.UUIDField(
        _("نمونه گردش کار"), null=True, blank=True,
    )

    submitted_date = models.DateField(_("تاریخ ارسال"), null=True, blank=True)
    decision_date = models.DateField(_("تاریخ تصمیم"), null=True, blank=True)
    implementation_date = models.DateField(_("تاریخ اجرا"), null=True, blank=True)
    decision_notes = models.TextField(_("یادداشت تصمیم"), 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 = "pm"
        db_table = "pm_change_request"
        verbose_name = _("درخواست تغییر")
        verbose_name_plural = _("درخواست‌های تغییر")
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.code} — {self.title}"


# ═══════════════════════════════════════════════════
# 1️⃣2️⃣ Timesheet
# ═══════════════════════════════════════════════════

class TimesheetModel(TenantAwareModel):
    """مدل ORM — تایم‌شیت."""

    # Override tenant related_name to avoid clash with HRM TimesheetModel
    tenant = models.ForeignKey(
        "tenant.Tenant", on_delete=models.CASCADE,
        related_name="pm_timesheet_set", db_index=True,
    )

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        SUBMITTED = "submitted", _("ارسال‌شده")
        APPROVED = "approved", _("تأیید‌شده")
        REJECTED = "rejected", _("ردشده")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="timesheets", verbose_name=_("پروژه"),
    )
    task = models.ForeignKey(
        TaskModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="timesheets",
        verbose_name=_("تسک"),
    )
    resource = models.ForeignKey(
        ResourceModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="timesheets",
        verbose_name=_("منبع"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_timesheets",
        verbose_name=_("کاربر"),
    )

    work_date = models.DateField(_("تاریخ کار"), db_index=True)
    regular_hours = models.DecimalField(
        _("ساعت عادی"), max_digits=5, decimal_places=2, default=0,
    )
    overtime_hours = models.DecimalField(
        _("ساعت اضافه‌کاری"), max_digits=5, decimal_places=2, default=0,
    )
    description = models.CharField(_("شرح فعالیت"), max_length=500, blank=True)

    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT, db_index=True,
    )
    approved_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_approved_timesheets",
        verbose_name=_("تأییدکننده"),
    )
    approved_date = models.DateField(_("تاریخ تأیید"), null=True, blank=True)
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_timesheet"
        verbose_name = _("تایم‌شیت")
        verbose_name_plural = _("تایم‌شیت‌ها")
        ordering = ["-work_date"]

    def __str__(self):
        return f"{self.user} — {self.work_date}"

    @property
    def total_hours(self):
        return self.regular_hours + self.overtime_hours


# ═══════════════════════════════════════════════════
# 1️⃣3️⃣ Project Member
# ═══════════════════════════════════════════════════

class ProjectMemberModel(TenantAwareModel):
    """مدل ORM — عضو پروژه."""

    class Role(models.TextChoices):
        MANAGER = "manager", _("مدیر")
        MEMBER = "member", _("عضو")
        VIEWER = "viewer", _("مشاهده‌کننده")
        STAKEHOLDER = "stakeholder", _("ذینفع")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="members", verbose_name=_("پروژه"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
        null=True, blank=True,
        related_name="pm_memberships", verbose_name=_("کاربر"),
    )

    role = models.CharField(
        _("نقش"), max_length=20,
        choices=Role.choices, default=Role.MEMBER,
    )
    is_active = models.BooleanField(_("فعال"), default=True)
    joined_date = models.DateField(_("تاریخ عضویت"), null=True, blank=True)
    left_date = models.DateField(_("تاریخ خروج"), null=True, blank=True)
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_project_member"
        verbose_name = _("عضو پروژه")
        verbose_name_plural = _("اعضای پروژه")

    def __str__(self):
        return f"{self.user} — {self.project} ({self.get_role_display()})"


# ═══════════════════════════════════════════════════
# 1️⃣4️⃣ Comment
# ═══════════════════════════════════════════════════

class CommentModel(TenantAwareModel):
    """مدل ORM — نظرات."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="comments", verbose_name=_("پروژه"),
    )
    task = models.ForeignKey(
        TaskModel, on_delete=models.CASCADE,
        null=True, blank=True, related_name="comments",
        verbose_name=_("تسک"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
        null=True, blank=True,
        related_name="pm_comments", verbose_name=_("کاربر"),
    )

    content = models.TextField(_("محتوا"))
    parent = models.ForeignKey(
        "self", on_delete=models.CASCADE,
        null=True, blank=True, related_name="replies",
        verbose_name=_("پاسخ به"),
    )
    mentions = models.JSONField(_("منشن‌ها"), default=list, blank=True)

    is_edited = models.BooleanField(_("ویرایش‌شده"), default=False)
    is_deleted = models.BooleanField(_("حذف‌شده"), default=False)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_comment"
        verbose_name = _("نظر")
        verbose_name_plural = _("نظرات")
        ordering = ["created_at"]

    def __str__(self):
        return f"نظر {self.user} در {self.project}"


# ═══════════════════════════════════════════════════
# 1️⃣5️⃣ Activity Log
# ═══════════════════════════════════════════════════

class ActivityLogModel(TenantAwareModel):
    """مدل ORM — لاگ فعالیت."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="activity_logs", verbose_name=_("پروژه"),
    )
    task = models.ForeignKey(
        TaskModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="activity_logs",
        verbose_name=_("تسک"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_activity_logs",
        verbose_name=_("کاربر"),
    )

    action = models.CharField(_("عمل"), max_length=50, db_index=True)
    entity_type = models.CharField(_("نوع موجودیت"), max_length=50)
    entity_id = models.UUIDField(_("شناسه موجودیت"), null=True, blank=True)

    description = models.TextField(_("شرح"), blank=True)
    changes = models.JSONField(_("تغییرات"), default=dict, blank=True)
    ip_address = models.GenericIPAddressField(_("آدرس IP"), null=True, blank=True)

    created_at = models.DateTimeField(_("تاریخ"), auto_now_add=True, db_index=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_activity_log"
        verbose_name = _("لاگ فعالیت")
        verbose_name_plural = _("لاگ فعالیت‌ها")
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.action} — {self.entity_type} — {self.created_at}"


# ═══════════════════════════════════════════════════
# 1️⃣6️⃣ Task Label (برچسب تسک — Kanban)
# ═══════════════════════════════════════════════════

class TaskLabelModel(TenantAwareModel):
    """مدل ORM — برچسب رنگی تسک (Kanban)."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="labels", verbose_name=_("پروژه"),
    )
    name = models.CharField(_("نام"), max_length=100)
    color = models.CharField(_("رنگ"), max_length=20, default="#3B82F6")
    description = models.CharField(_("توضیحات"), max_length=255, blank=True)
    sort_order = models.IntegerField(_("ترتیب"), default=0)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_task_label"
        verbose_name = _("برچسب تسک")
        verbose_name_plural = _("برچسب‌های تسک")
        ordering = ["sort_order", "name"]
        unique_together = [("project", "name")]

    def __str__(self):
        return f"{self.name} — {self.project}"


class TaskLabelAssignmentModel(TenantAwareModel):
    """ارتباط M2M بین تسک و برچسب."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    task = models.ForeignKey(
        TaskModel, on_delete=models.CASCADE,
        related_name="label_assignments", verbose_name=_("تسک"),
    )
    label = models.ForeignKey(
        TaskLabelModel, on_delete=models.CASCADE,
        related_name="task_assignments", verbose_name=_("برچسب"),
    )
    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_task_label_assignment"
        verbose_name = _("اختصاص برچسب")
        verbose_name_plural = _("اختصاص برچسب‌ها")
        unique_together = [("task", "label")]

    def __str__(self):
        return f"{self.task} ← {self.label}"


# ═══════════════════════════════════════════════════
# 1️⃣7️⃣ Task Attachment (پیوست فایل — Kanban)
# ═══════════════════════════════════════════════════

class TaskAttachmentModel(TenantAwareModel):
    """مدل ORM — فایل پیوست تسک."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    task = models.ForeignKey(
        TaskModel, on_delete=models.CASCADE,
        related_name="attachments", verbose_name=_("تسک"),
    )
    file_name = models.CharField(_("نام فایل"), max_length=255)
    file_url = models.URLField(_("آدرس فایل"), max_length=1024)
    file_size = models.PositiveIntegerField(_("حجم (بایت)"), default=0)
    mime_type = models.CharField(_("نوع فایل"), max_length=100, blank=True)
    uploaded_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_attachments",
        verbose_name=_("آپلودکننده"),
    )

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_task_attachment"
        verbose_name = _("پیوست")
        verbose_name_plural = _("پیوست‌ها")
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.file_name} — {self.task}"


# ═══════════════════════════════════════════════════
# 1️⃣8️⃣ Task Checklist (چک‌لیست — Kanban)
# ═══════════════════════════════════════════════════

class TaskChecklistModel(TenantAwareModel):
    """مدل ORM — چک‌لیست تسک."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    task = models.ForeignKey(
        TaskModel, on_delete=models.CASCADE,
        related_name="checklists", verbose_name=_("تسک"),
    )
    title = models.CharField(_("عنوان"), max_length=255)
    sort_order = models.IntegerField(_("ترتیب"), default=0)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_task_checklist"
        verbose_name = _("چک‌لیست")
        verbose_name_plural = _("چک‌لیست‌ها")
        ordering = ["sort_order"]

    def __str__(self):
        return f"{self.title} — {self.task}"

    @property
    def progress(self):
        total = self.items.count()
        if total == 0:
            return 0
        done = self.items.filter(is_checked=True).count()
        return round(done / total * 100)


class TaskChecklistItemModel(TenantAwareModel):
    """مدل ORM — آیتم چک‌لیست."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    checklist = models.ForeignKey(
        TaskChecklistModel, on_delete=models.CASCADE,
        related_name="items", verbose_name=_("چک‌لیست"),
    )
    title = models.CharField(_("عنوان"), max_length=500)
    is_checked = models.BooleanField(_("انجام‌شده"), default=False)
    assignee = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_checklist_items",
        verbose_name=_("مسئول"),
    )
    due_date = models.DateField(_("مهلت"), null=True, blank=True)
    sort_order = models.IntegerField(_("ترتیب"), default=0)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_task_checklist_item"
        verbose_name = _("آیتم چک‌لیست")
        verbose_name_plural = _("آیتم‌های چک‌لیست")
        ordering = ["sort_order"]

    def __str__(self):
        mark = "✓" if self.is_checked else "○"
        return f"{mark} {self.title}"


# ═══════════════════════════════════════════════════
# 1️⃣9️⃣ RACI Assignment (سطوح دسترسی RACI)
# ═══════════════════════════════════════════════════

class RACIAssignmentModel(TenantAwareModel):
    """مدل ORM — اختصاص نقش RACI در سطح پروژه و تسک."""

    class RACIRole(models.TextChoices):
        RESPONSIBLE = "R", _("مسئول (Responsible)")
        ACCOUNTABLE = "A", _("پاسخگو (Accountable)")
        CONSULTED = "C", _("مشاوره (Consulted)")
        INFORMED = "I", _("مطلع (Informed)")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="raci_assignments", verbose_name=_("پروژه"),
    )
    task = models.ForeignKey(
        TaskModel, on_delete=models.CASCADE,
        null=True, blank=True, related_name="raci_assignments",
        verbose_name=_("تسک"),
        help_text=_("اگر خالی باشد، RACI در سطح پروژه اعمال می‌شود"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
        null=True, blank=True,
        related_name="pm_raci_assignments", verbose_name=_("کاربر"),
    )
    resource = models.ForeignKey(
        ResourceModel, on_delete=models.CASCADE,
        null=True, blank=True,
        related_name="raci_assignments", verbose_name=_("منبع"),
        help_text=_("منبع انسانی مرتبط — جایگزین user برای fixture"),
    )
    role = models.CharField(
        _("نقش RACI"), max_length=1,
        choices=RACIRole.choices,
    )
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_raci_assignment"
        verbose_name = _("اختصاص RACI")
        verbose_name_plural = _("اختصاص‌های RACI")
        unique_together = [("project", "task", "user", "resource", "role")]
        ordering = ["project", "task", "role"]

    def __str__(self):
        scope = f"تسک {self.task}" if self.task else f"پروژه {self.project}"
        person = self.user or self.resource or "نامشخص"
        return f"{person} — {self.get_role_display()} — {scope}"


# ═══════════════════════════════════════════════════
# 2️⃣0️⃣ Activity Code Type (نوع کد فعالیت)
# ═══════════════════════════════════════════════════

class ActivityCodeTypeModel(TenantAwareModel):
    """مدل ORM — نوع کد فعالیت (مثل Phase, Discipline, Location)."""

    class Scope(models.TextChoices):
        GLOBAL = "global", _("سراسری")
        PROJECT = "project", _("سطح پروژه")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("نام"), max_length=200)
    code = models.CharField(_("کد"), max_length=50, db_index=True)
    description = models.TextField(_("توضیحات"), blank=True)
    scope = models.CharField(
        _("محدوده"), max_length=10,
        choices=Scope.choices, default=Scope.GLOBAL,
    )
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        null=True, blank=True, related_name="activity_code_types",
        verbose_name=_("پروژه"),
        help_text=_("اگر scope=project باشد"),
    )
    is_active = models.BooleanField(_("فعال"), default=True)
    sort_order = models.IntegerField(_("ترتیب"), default=0)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_activity_code_type"
        verbose_name = _("نوع کد فعالیت")
        verbose_name_plural = _("انواع کد فعالیت")
        unique_together = [("code", "tenant_id")]
        ordering = ["sort_order", "name"]

    def __str__(self):
        return f"{self.code} — {self.name}"


# ═══════════════════════════════════════════════════
# 2️⃣1️⃣ Activity Code Value (مقدار کد فعالیت)
# ═══════════════════════════════════════════════════

class ActivityCodeValueModel(TenantAwareModel):
    """مدل ORM — مقدار کد فعالیت (مثلاً Phase=Design)."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    code_type = models.ForeignKey(
        ActivityCodeTypeModel, on_delete=models.CASCADE,
        related_name="values", verbose_name=_("نوع کد"),
    )
    parent = models.ForeignKey(
        "self", on_delete=models.CASCADE,
        null=True, blank=True, related_name="children",
        verbose_name=_("والد"),
    )
    code = models.CharField(_("کد"), max_length=50)
    name = models.CharField(_("نام"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)
    color = models.CharField(_("رنگ"), max_length=20, blank=True)
    sort_order = models.IntegerField(_("ترتیب"), default=0)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_activity_code_value"
        verbose_name = _("مقدار کد فعالیت")
        verbose_name_plural = _("مقادیر کد فعالیت")
        unique_together = [("code_type", "code")]
        ordering = ["sort_order", "code"]

    def __str__(self):
        return f"{self.code_type.code}:{self.code} — {self.name}"


# ═══════════════════════════════════════════════════
# 2️⃣2️⃣ Task Activity Code (اختصاص کد فعالیت به تسک)
# ═══════════════════════════════════════════════════

class TaskActivityCodeModel(TenantAwareModel):
    """مدل ORM — اختصاص مقدار کد فعالیت به یک تسک."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    task = models.ForeignKey(
        TaskModel, on_delete=models.CASCADE,
        related_name="activity_codes", verbose_name=_("تسک"),
    )
    code_value = models.ForeignKey(
        ActivityCodeValueModel, on_delete=models.CASCADE,
        related_name="task_assignments", verbose_name=_("مقدار کد"),
    )

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_task_activity_code"
        verbose_name = _("کد فعالیت تسک")
        verbose_name_plural = _("کدهای فعالیت تسک")
        unique_together = [("task", "code_value")]

    def __str__(self):
        return f"{self.task} → {self.code_value}"


# ═══════════════════════════════════════════════════
# 2️⃣3️⃣ UDF Definition (تعریف فیلد سفارشی)
# ═══════════════════════════════════════════════════

class UDFDefinitionModel(TenantAwareModel):
    """مدل ORM — تعریف فیلد سفارشی (EAV pattern)."""

    class FieldType(models.TextChoices):
        TEXT = "text", _("متنی")
        NUMBER = "number", _("عددی")
        DATE = "date", _("تاریخ")
        BOOLEAN = "boolean", _("بولی")
        SELECT = "select", _("انتخابی")
        MULTI_SELECT = "multi_select", _("چندانتخابی")

    class EntityType(models.TextChoices):
        TASK = "task", _("تسک")
        PROJECT = "project", _("پروژه")
        RESOURCE = "resource", _("منبع")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("نام"), max_length=200)
    code = models.CharField(_("کد"), max_length=100, db_index=True)
    description = models.TextField(_("توضیحات"), blank=True)
    field_type = models.CharField(
        _("نوع فیلد"), max_length=20,
        choices=FieldType.choices, default=FieldType.TEXT,
    )
    entity_type = models.CharField(
        _("نوع موجودیت"), max_length=20,
        choices=EntityType.choices, default=EntityType.TASK,
    )
    default_value = models.TextField(_("مقدار پیش‌فرض"), blank=True)
    options = models.JSONField(
        _("گزینه‌ها"), default=list, blank=True,
        help_text=_("برای فیلدهای select/multi_select"),
    )
    is_required = models.BooleanField(_("اجباری"), default=False)
    is_active = models.BooleanField(_("فعال"), default=True)
    sort_order = models.IntegerField(_("ترتیب"), default=0)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_udf_definition"
        verbose_name = _("تعریف فیلد سفارشی")
        verbose_name_plural = _("تعاریف فیلد سفارشی")
        unique_together = [("code", "entity_type", "tenant_id")]
        ordering = ["entity_type", "sort_order"]

    def __str__(self):
        return f"{self.name} ({self.entity_type}/{self.field_type})"


# ═══════════════════════════════════════════════════
# 2️⃣4️⃣ UDF Value (مقدار فیلد سفارشی)
# ═══════════════════════════════════════════════════

class UDFValueModel(TenantAwareModel):
    """مدل ORM — مقدار فیلد سفارشی (EAV row)."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    definition = models.ForeignKey(
        UDFDefinitionModel, on_delete=models.CASCADE,
        related_name="values", verbose_name=_("تعریف فیلد"),
    )
    entity_id = models.UUIDField(_("شناسه موجودیت"), db_index=True)
    entity_type = models.CharField(_("نوع موجودیت"), max_length=20)

    value_text = models.TextField(_("مقدار متنی"), blank=True)
    value_number = models.DecimalField(
        _("مقدار عددی"), max_digits=20, decimal_places=4,
        null=True, blank=True,
    )
    value_date = models.DateField(_("مقدار تاریخ"), null=True, blank=True)
    value_boolean = models.BooleanField(_("مقدار بولی"), null=True, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_udf_value"
        verbose_name = _("مقدار فیلد سفارشی")
        verbose_name_plural = _("مقادیر فیلد سفارشی")
        unique_together = [("definition", "entity_id")]
        indexes = [
            models.Index(
                fields=["entity_type", "entity_id"],
                name="pm_udf_val_entity_idx",
            ),
        ]

    def __str__(self):
        return f"{self.definition.name}: {self.get_display_value()}"

    def get_display_value(self):
        if self.definition.field_type == "number":
            return self.value_number
        elif self.definition.field_type == "date":
            return self.value_date
        elif self.definition.field_type == "boolean":
            return self.value_boolean
        return self.value_text


# ═══════════════════════════════════════════════════
# 2️⃣5️⃣ Resource Skill (مهارت منبع)
# ═══════════════════════════════════════════════════

class ResourceSkillModel(TenantAwareModel):
    """مدل ORM — مهارت منبع."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    resource = models.ForeignKey(
        ResourceModel, on_delete=models.CASCADE,
        related_name="skills", verbose_name=_("منبع"),
    )
    skill_name = models.CharField(_("نام مهارت"), max_length=200)
    proficiency_level = models.IntegerField(
        _("سطح مهارت"), default=1,
        help_text=_("۱ تا ۵"),
    )
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_resource_skill"
        verbose_name = _("مهارت منبع")
        verbose_name_plural = _("مهارت‌های منبع")
        unique_together = [("resource", "skill_name")]

    def __str__(self):
        return f"{self.resource} — {self.skill_name} (L{self.proficiency_level})"


# ═══════════════════════════════════════════════════
# 2️⃣6️⃣ Resource Availability (دسترسی منبع)
# ═══════════════════════════════════════════════════

class ResourceAvailabilityModel(TenantAwareModel):
    """مدل ORM — دوره دسترسی منبع."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    resource = models.ForeignKey(
        ResourceModel, on_delete=models.CASCADE,
        related_name="availability_periods", verbose_name=_("منبع"),
    )
    start_date = models.DateField(_("تاریخ شروع"))
    end_date = models.DateField(_("تاریخ پایان"), null=True, blank=True)
    available_units = models.DecimalField(
        _("واحد در دسترس (٪)"), max_digits=6, decimal_places=2, default=100,
    )
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_resource_availability"
        verbose_name = _("دسترسی منبع")
        verbose_name_plural = _("دوره‌های دسترسی منبع")
        ordering = ["resource", "start_date"]

    def __str__(self):
        return f"{self.resource}: {self.start_date} → {self.end_date or '∞'} ({self.available_units}%)"


# ═══════════════════════════════════════════════════
# 2️⃣7️⃣ Resource Cost Rate (نرخ هزینه منبع)
# ═══════════════════════════════════════════════════

class ResourceCostRateModel(TenantAwareModel):
    """مدل ORM — جدول نرخ هزینه منبع بر اساس تاریخ."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    resource = models.ForeignKey(
        ResourceModel, on_delete=models.CASCADE,
        related_name="cost_rates", verbose_name=_("منبع"),
    )
    effective_date = models.DateField(_("تاریخ اعمال"))
    standard_rate = models.DecimalField(
        _("نرخ استاندارد"), max_digits=14, decimal_places=2, default=0,
    )
    overtime_rate = models.DecimalField(
        _("نرخ اضافه‌کار"), max_digits=14, decimal_places=2, default=0,
    )
    cost_per_use = models.DecimalField(
        _("هزینه هر استفاده"), max_digits=14, decimal_places=2, default=0,
    )
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_resource_cost_rate"
        verbose_name = _("نرخ هزینه منبع")
        verbose_name_plural = _("نرخ‌های هزینه منبع")
        unique_together = [("resource", "effective_date")]
        ordering = ["resource", "-effective_date"]

    def __str__(self):
        return f"{self.resource}: {self.effective_date} — {self.standard_rate}"


# ═══════════════════════════════════════════════════
# 2️⃣8️⃣ Cost Account — CBS (ساختار شکست هزینه)
# ═══════════════════════════════════════════════════

class CostAccountModel(TenantAwareModel):
    """مدل ORM — حساب هزینه (CBS hierarchy)."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="cost_accounts", verbose_name=_("پروژه"),
    )
    parent = models.ForeignKey(
        "self", on_delete=models.CASCADE,
        null=True, blank=True, related_name="children",
        verbose_name=_("والد"),
    )
    code = models.CharField(_("کد"), max_length=50, db_index=True)
    name = models.CharField(_("نام"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)
    budget_amount = models.DecimalField(
        _("بودجه"), max_digits=18, decimal_places=2, default=0,
    )
    actual_amount = models.DecimalField(
        _("هزینه واقعی"), max_digits=18, decimal_places=2, default=0,
    )
    sort_order = models.IntegerField(_("ترتیب"), default=0)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_cost_account"
        verbose_name = _("حساب هزینه")
        verbose_name_plural = _("حساب‌های هزینه")
        unique_together = [("project", "code")]
        ordering = ["sort_order", "code"]

    def __str__(self):
        return f"{self.code} — {self.name}"

    @property
    def variance(self):
        return self.budget_amount - self.actual_amount


# ═══════════════════════════════════════════════════
# 2️⃣9️⃣ Funding Source (منبع مالی)
# ═══════════════════════════════════════════════════

class FundingSourceModel(TenantAwareModel):
    """مدل ORM — منبع مالی پروژه."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="funding_sources", verbose_name=_("پروژه"),
    )
    name = models.CharField(_("نام"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)
    total_amount = models.DecimalField(
        _("مبلغ کل"), max_digits=18, decimal_places=2, default=0,
    )
    allocated_amount = models.DecimalField(
        _("مبلغ تخصیص‌یافته"), max_digits=18, decimal_places=2, default=0,
    )
    remaining_amount = models.DecimalField(
        _("مبلغ باقی‌مانده"), max_digits=18, decimal_places=2, default=0,
    )
    start_date = models.DateField(_("تاریخ شروع"), null=True, blank=True)
    end_date = models.DateField(_("تاریخ پایان"), null=True, 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 = "pm"
        db_table = "pm_funding_source"
        verbose_name = _("منبع مالی")
        verbose_name_plural = _("منابع مالی")
        ordering = ["project", "name"]

    def __str__(self):
        return f"{self.name} — {self.total_amount}"


# ═══════════════════════════════════════════════════
# 3️⃣0️⃣ Cash Flow Entry (جریان نقدی)
# ═══════════════════════════════════════════════════

class CashFlowEntryModel(TenantAwareModel):
    """مدل ORM — جریان نقدی دوره‌ای."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="cash_flows", verbose_name=_("پروژه"),
    )
    period_start = models.DateField(_("شروع دوره"))
    period_end = models.DateField(_("پایان دوره"), null=True, blank=True)
    planned_income = models.DecimalField(
        _("درآمد برنامه‌ای"), max_digits=18, decimal_places=2, default=0,
    )
    planned_expense = models.DecimalField(
        _("هزینه برنامه‌ای"), max_digits=18, decimal_places=2, default=0,
    )
    actual_income = models.DecimalField(
        _("درآمد واقعی"), max_digits=18, decimal_places=2, default=0,
    )
    actual_expense = models.DecimalField(
        _("هزینه واقعی"), max_digits=18, decimal_places=2, default=0,
    )
    notes = models.TextField(_("یادداشت"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_cash_flow_entry"
        verbose_name = _("جریان نقدی")
        verbose_name_plural = _("جریان‌های نقدی")
        ordering = ["project", "period_start"]
        unique_together = [("project", "period_start")]

    def __str__(self):
        return f"{self.project}: {self.period_start}"

    @property
    def net_planned(self):
        return self.planned_income - self.planned_expense

    @property
    def net_actual(self):
        return self.actual_income - self.actual_expense


# ═══════════════════════════════════════════════════
# 3️⃣1️⃣ Schedule Health Snapshot (اسنپ‌شات سلامت زمان‌بندی)
# ═══════════════════════════════════════════════════

class ScheduleHealthSnapshotModel(TenantAwareModel):
    """مدل ORM — اسنپ‌شات سلامت زمان‌بندی."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="health_snapshots", verbose_name=_("پروژه"),
    )
    snapshot_date = models.DateField(_("تاریخ اسنپ‌شات"))

    # KPIs
    bei = models.DecimalField(
        _("BEI"), max_digits=6, decimal_places=3, null=True, blank=True,
        help_text=_("Baseline Execution Index"),
    )
    cpli = models.DecimalField(
        _("CPLI"), max_digits=6, decimal_places=3, null=True, blank=True,
        help_text=_("Critical Path Length Index"),
    )
    spi = models.DecimalField(
        _("SPI"), max_digits=6, decimal_places=3, null=True, blank=True,
        help_text=_("Schedule Performance Index"),
    )

    # Counts
    critical_tasks_count = models.IntegerField(_("تسک‌های بحرانی"), default=0)
    total_tasks_count = models.IntegerField(_("کل تسک‌ها"), default=0)
    out_of_sequence_count = models.IntegerField(_("خارج از ترتیب"), default=0)
    missing_logic_count = models.IntegerField(_("بدون منطق"), default=0)
    negative_float_count = models.IntegerField(_("شناوری منفی"), default=0)
    high_float_count = models.IntegerField(_("شناوری بالا"), default=0)

    # Score
    health_score = models.IntegerField(
        _("امتیاز سلامت"), default=0,
        help_text=_("0 تا 100"),
    )
    details = models.JSONField(_("جزئیات"), default=dict, blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_schedule_health_snapshot"
        verbose_name = _("اسنپ‌شات سلامت")
        verbose_name_plural = _("اسنپ‌شات‌های سلامت")
        unique_together = [("project", "snapshot_date")]
        ordering = ["project", "-snapshot_date"]

    def __str__(self):
        return f"{self.project}: {self.snapshot_date} — Score {self.health_score}"


# ═══════════════════════════════════════════════════
# 3️⃣2️⃣ Project Template (قالب پروژه)
# ═══════════════════════════════════════════════════

class ProjectTemplateModel(TenantAwareModel):
    """مدل ORM — قالب پروژه."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(_("نام"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)
    category = models.CharField(_("دسته‌بندی"), max_length=100, blank=True)
    template_data = models.JSONField(
        _("داده قالب"), default=dict, blank=True,
        help_text=_("شامل WBS, Tasks, Dependencies, Resources, ..."),
    )
    is_active = models.BooleanField(_("فعال"), default=True)
    usage_count = models.IntegerField(_("تعداد استفاده"), default=0)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_project_template"
        verbose_name = _("قالب پروژه")
        verbose_name_plural = _("قالب‌های پروژه")
        ordering = ["-usage_count", "name"]

    def __str__(self):
        return self.name


# ═══════════════════════════════════════════════════
# 3️⃣3️⃣ Issue (لاگ مسائل)
# ═══════════════════════════════════════════════════

class IssueModel(TenantAwareModel):
    """مدل ORM — مسئله پروژه (Issue Log)."""

    class Category(models.TextChoices):
        TECHNICAL = "technical", _("فنی")
        RESOURCE = "resource", _("منابع")
        SCHEDULE = "schedule", _("زمان‌بندی")
        COST = "cost", _("هزینه")
        SCOPE = "scope", _("دامنه")
        QUALITY = "quality", _("کیفیت")
        COMMUNICATION = "communication", _("ارتباطات")
        OTHER = "other", _("سایر")

    class Severity(models.TextChoices):
        CRITICAL = "critical", _("بحرانی")
        MAJOR = "major", _("عمده")
        MODERATE = "moderate", _("متوسط")
        MINOR = "minor", _("جزئی")

    class Priority(models.TextChoices):
        CRITICAL = "critical", _("بحرانی")
        HIGH = "high", _("بالا")
        MEDIUM = "medium", _("متوسط")
        LOW = "low", _("پایین")

    class Status(models.TextChoices):
        OPEN = "open", _("باز")
        IN_PROGRESS = "in_progress", _("در حال رسیدگی")
        ON_HOLD = "on_hold", _("متوقف")
        RESOLVED = "resolved", _("حل‌شده")
        CLOSED = "closed", _("بسته‌شده")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="issues", verbose_name=_("پروژه"),
    )

    code = models.CharField(_("کد مسئله"), max_length=50, db_index=True)
    title = models.CharField(_("عنوان"), max_length=500)
    description = models.TextField(_("شرح"), blank=True)

    category = models.CharField(
        _("دسته‌بندی"), max_length=20,
        choices=Category.choices, default=Category.OTHER,
    )
    severity = models.CharField(
        _("شدت"), max_length=20,
        choices=Severity.choices, default=Severity.MODERATE,
    )
    priority = models.CharField(
        _("اولویت"), max_length=20,
        choices=Priority.choices, default=Priority.MEDIUM,
    )
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.OPEN, db_index=True,
    )

    # --- People ---
    reporter = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_reported_issues",
        verbose_name=_("گزارش‌دهنده"),
    )
    assignee = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_assigned_issues",
        verbose_name=_("مسئول رسیدگی"),
    )

    # --- Relations ---
    affected_tasks = models.JSONField(_("فعالیت‌های تأثیرپذیر"), default=list, blank=True)
    related_risk = models.ForeignKey(
        RiskModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="issues",
        verbose_name=_("ریسک مرتبط"),
    )

    # --- Resolution ---
    resolution = models.TextField(_("راه‌حل"), blank=True)
    impact_description = models.TextField(_("شرح تأثیر"), blank=True)

    # --- Impact ---
    cost_impact = models.DecimalField(
        _("تأثیر هزینه‌ای"), max_digits=18, decimal_places=0, default=0,
    )
    schedule_impact_days = models.IntegerField(_("تأثیر زمانی (روز)"), default=0)

    # --- Dates ---
    identified_date = models.DateField(_("تاریخ شناسایی"), null=True, blank=True)
    due_date = models.DateField(_("مهلت رسیدگی"), null=True, blank=True)
    resolved_date = models.DateField(_("تاریخ حل"), null=True, blank=True)
    closed_date = models.DateField(_("تاریخ بسته‌شدن"), null=True, blank=True)

    # --- Metadata ---
    notes = models.TextField(_("یادداشت"), blank=True)
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    # --- Audit ---
    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_issue"
        verbose_name = _("مسئله")
        verbose_name_plural = _("مسائل")
        ordering = ["-created_at"]
        unique_together = [("tenant", "project", "code")]

    def __str__(self):
        return f"{self.code} — {self.title}"


# ═══════════════════════════════════════════════════
# 3️⃣4️⃣ OBS Node (ساختار شکست سازمانی)
# ═══════════════════════════════════════════════════

class OBSNodeModel(TenantAwareModel):
    """مدل ORM — گره ساختار شکست سازمانی (OBS)."""

    class NodeType(models.TextChoices):
        DEPARTMENT = "department", _("دپارتمان")
        DIVISION = "division", _("بخش")
        TEAM = "team", _("تیم")
        INDIVIDUAL = "individual", _("فرد")
        EXTERNAL = "external", _("پیمانکار/خارجی")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="obs_nodes", verbose_name=_("پروژه"),
    )
    parent = models.ForeignKey(
        "self", on_delete=models.CASCADE,
        null=True, blank=True, related_name="children",
        verbose_name=_("والد"),
    )

    # --- Identification ---
    code = models.CharField(_("کد"), max_length=50, db_index=True)
    name = models.CharField(_("نام"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)

    # --- Classification ---
    node_type = models.CharField(
        _("نوع گره"), max_length=20,
        choices=NodeType.choices, default=NodeType.DEPARTMENT,
    )
    level = models.IntegerField(_("سطح"), default=0)

    # --- Assignment ---
    manager = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="pm_obs_managed_nodes",
        verbose_name=_("مدیر/مسئول"),
    )
    org_unit_id = models.UUIDField(
        _("واحد سازمانی مرجع"), null=True, blank=True,
    )

    # --- Details ---
    responsibilities = models.TextField(_("شرح مسئولیت‌ها"), blank=True)
    is_active = models.BooleanField(_("فعال"), default=True)
    sort_order = models.IntegerField(_("ترتیب"), default=0)

    # --- Metadata ---
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    # --- Audit ---
    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_obs_node"
        verbose_name = _("گره OBS")
        verbose_name_plural = _("گره‌های OBS")
        ordering = ["sort_order", "code"]
        unique_together = [("project", "code")]

    def __str__(self):
        return f"{self.code} — {self.name}"


# ═══════════════════════════════════════════════════
# 3️⃣5️⃣ RBS Node (ساختار شکست منابع)
# ═══════════════════════════════════════════════════

class RBSNodeModel(TenantAwareModel):
    """مدل ORM — گره ساختار شکست منابع (RBS)."""

    class NodeType(models.TextChoices):
        CATEGORY = "category", _("دسته‌بندی")
        HUMAN = "human", _("نیروی انسانی")
        EQUIPMENT = "equipment", _("تجهیزات")
        MATERIAL = "material", _("مواد")
        FACILITY = "facility", _("تأسیسات")
        FINANCIAL = "financial", _("مالی")
        INFORMATION = "information", _("اطلاعاتی")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="rbs_nodes", verbose_name=_("پروژه"),
    )
    parent = models.ForeignKey(
        "self", on_delete=models.CASCADE,
        null=True, blank=True, related_name="children",
        verbose_name=_("والد"),
    )

    # --- Identification ---
    code = models.CharField(_("کد"), max_length=50, db_index=True)
    name = models.CharField(_("نام"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)

    # --- Classification ---
    node_type = models.CharField(
        _("نوع گره"), max_length=20,
        choices=NodeType.choices, default=NodeType.CATEGORY,
    )
    level = models.IntegerField(_("سطح"), default=0)

    # --- Resource Info ---
    resource_type = models.CharField(_("نوع منبع"), max_length=50, blank=True)
    unit = models.CharField(_("واحد"), max_length=50, blank=True)
    default_rate = models.DecimalField(
        _("نرخ پیش‌فرض"), max_digits=18, decimal_places=2, default=0,
    )

    # --- Details ---
    is_active = models.BooleanField(_("فعال"), default=True)
    sort_order = models.IntegerField(_("ترتیب"), default=0)

    # --- Metadata ---
    metadata = models.JSONField(_("متادیتا"), default=dict, blank=True)

    # --- Audit ---
    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_rbs_node"
        verbose_name = _("گره RBS")
        verbose_name_plural = _("گره‌های RBS")
        ordering = ["sort_order", "code"]
        unique_together = [("project", "code")]

    def __str__(self):
        return f"{self.code} — {self.name}"


# ═══════════════════════════════════════════════════
# Quality Plan Model
# ═══════════════════════════════════════════════════

class QualityPlanModel(TenantAwareModel):
    """مدل ORM — طرح کیفیت."""

    class Status(models.TextChoices):
        DRAFT = "draft", _("پیش‌نویس")
        ACTIVE = "active", _("فعال")
        UNDER_REVIEW = "under_review", _("در حال بازبینی")
        APPROVED = "approved", _("تأیید‌شده")
        ARCHIVED = "archived", _("بایگانی")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="quality_plans", verbose_name=_("پروژه"),
    )
    name = models.CharField(_("نام"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.DRAFT,
    )
    criteria = models.TextField(_("معیارهای پذیرش"), blank=True)
    standards = models.TextField(_("استانداردهای مرجع"), blank=True)
    objectives = models.TextField(_("اهداف کیفیت"), blank=True)
    scope = models.TextField(_("محدوده"), blank=True)

    quality_manager = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="managed_quality_plans",
        verbose_name=_("مدیر کیفیت"),
    )

    effective_date = models.DateField(_("تاریخ اجرا"), null=True, blank=True)
    review_date = models.DateField(_("تاریخ بازبینی"), null=True, blank=True)

    version = models.CharField(_("نسخه"), max_length=20, default="1.0")
    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 = "pm"
        db_table = "pm_quality_plan"
        verbose_name = _("طرح کیفیت")
        verbose_name_plural = _("طرح‌های کیفیت")
        ordering = ["-created_at"]

    def __str__(self):
        return self.name


# ═══════════════════════════════════════════════════
# Inspection Model
# ═══════════════════════════════════════════════════

class InspectionModel(TenantAwareModel):
    """مدل ORM — بازرسی کیفیت."""

    class InspectionType(models.TextChoices):
        QUALITY_AUDIT = "quality_audit", _("ممیزی کیفیت")
        PROCESS_INSPECTION = "process_inspection", _("بازرسی فرآیند")
        PRODUCT_INSPECTION = "product_inspection", _("بازرسی محصول")
        MILESTONE_REVIEW = "milestone_review", _("بازبینی نقطه عطف")
        FINAL_INSPECTION = "final_inspection", _("بازرسی نهایی")
        RANDOM_SAMPLING = "random_sampling", _("نمونه‌برداری تصادفی")

    class Status(models.TextChoices):
        PLANNED = "planned", _("برنامه‌ریزی‌شده")
        IN_PROGRESS = "in_progress", _("در حال انجام")
        COMPLETED = "completed", _("تکمیل‌شده")
        CANCELLED = "cancelled", _("لغو‌شده")

    class Result(models.TextChoices):
        PASSED = "passed", _("قبول")
        FAILED = "failed", _("مردود")
        CONDITIONAL = "conditional", _("مشروط")
        NOT_APPLICABLE = "na", _("غیرقابل‌اعمال")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="inspections", verbose_name=_("پروژه"),
    )
    quality_plan = models.ForeignKey(
        'QualityPlanModel', on_delete=models.SET_NULL,
        null=True, blank=True, related_name="inspections",
        verbose_name=_("طرح کیفیت"),
    )
    task = models.ForeignKey(
        TaskModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="inspections",
        verbose_name=_("فعالیت"),
    )

    code = models.CharField(_("کد"), max_length=50, db_index=True)
    title = models.CharField(_("عنوان"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)

    inspection_type = models.CharField(
        _("نوع بازرسی"), max_length=30,
        choices=InspectionType.choices, default=InspectionType.QUALITY_AUDIT,
    )
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.PLANNED,
    )
    result = models.CharField(
        _("نتیجه"), max_length=20,
        choices=Result.choices, default=Result.NOT_APPLICABLE,
    )

    inspector = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="inspections",
        verbose_name=_("بازرس"),
    )

    findings = models.TextField(_("یافته‌ها"), blank=True)
    recommendations = models.TextField(_("توصیه‌ها"), blank=True)

    planned_date = models.DateField(_("تاریخ برنامه‌ریزی"), null=True, blank=True)
    actual_date = models.DateField(_("تاریخ واقعی"), 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 = "pm"
        db_table = "pm_inspection"
        verbose_name = _("بازرسی")
        verbose_name_plural = _("بازرسی‌ها")
        ordering = ["-created_at"]
        unique_together = [("project", "code")]

    def __str__(self):
        return f"{self.code} — {self.title}"


# ═══════════════════════════════════════════════════
# NCR Model
# ═══════════════════════════════════════════════════

class NCRModel(TenantAwareModel):
    """مدل ORM — گزارش عدم انطباق."""

    class Severity(models.TextChoices):
        MINOR = "minor", _("جزئی")
        MAJOR = "major", _("عمده")
        CRITICAL = "critical", _("بحرانی")

    class Status(models.TextChoices):
        OPEN = "open", _("باز")
        UNDER_REVIEW = "under_review", _("در حال بررسی")
        ACTION_REQUIRED = "action_required", _("نیاز به اقدام")
        IN_PROGRESS = "in_progress", _("در حال رفع")
        RESOLVED = "resolved", _("رفع‌شده")
        VERIFIED = "verified", _("تأیید شده")
        CLOSED = "closed", _("بسته")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="ncrs", verbose_name=_("پروژه"),
    )
    inspection = models.ForeignKey(
        InspectionModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="ncrs",
        verbose_name=_("بازرسی"),
    )
    task = models.ForeignKey(
        TaskModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="ncrs",
        verbose_name=_("فعالیت"),
    )

    code = models.CharField(_("کد"), max_length=50, db_index=True)
    title = models.CharField(_("عنوان"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)

    severity = models.CharField(
        _("شدت"), max_length=20,
        choices=Severity.choices, default=Severity.MINOR,
    )
    status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=Status.choices, default=Status.OPEN,
    )

    reported_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="reported_ncrs",
        verbose_name=_("گزارش‌دهنده"),
    )
    assigned_to = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="assigned_ncrs",
        verbose_name=_("مسئول رفع"),
    )

    root_cause = models.TextField(_("علت ریشه‌ای"), blank=True)
    corrective_action = models.TextField(_("اقدام اصلاحی"), blank=True)
    preventive_action = models.TextField(_("اقدام پیشگیرانه"), blank=True)

    cost_impact = models.DecimalField(
        _("تأثیر مالی"), max_digits=18, decimal_places=2, default=0,
    )
    schedule_impact_days = models.IntegerField(_("تأثیر زمانی (روز)"), default=0)

    identified_date = models.DateField(_("تاریخ شناسایی"), null=True, blank=True)
    due_date = models.DateField(_("سررسید"), null=True, blank=True)
    resolved_date = models.DateField(_("تاریخ رفع"), null=True, blank=True)
    closed_date = models.DateField(_("تاریخ بستن"), 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 = "pm"
        db_table = "pm_ncr"
        verbose_name = _("عدم انطباق")
        verbose_name_plural = _("عدم انطباق‌ها")
        ordering = ["-created_at"]
        unique_together = [("project", "code")]

    def __str__(self):
        return f"{self.code} — {self.title}"


# ═══════════════════════════════════════════════════
# Quality Checklist Model
# ═══════════════════════════════════════════════════

class QualityChecklistModel(TenantAwareModel):
    """مدل ORM — چک‌لیست کیفیت."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="quality_checklists", verbose_name=_("پروژه"),
    )
    quality_plan = models.ForeignKey(
        'QualityPlanModel', on_delete=models.SET_NULL,
        null=True, blank=True, related_name="checklists",
        verbose_name=_("طرح کیفیت"),
    )
    task = models.ForeignKey(
        TaskModel, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="quality_checklists",
        verbose_name=_("فعالیت"),
    )

    name = models.CharField(_("نام"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)

    is_completed = models.BooleanField(_("تکمیل‌شده"), default=False)
    completed_date = models.DateField(_("تاریخ تکمیل"), null=True, blank=True)
    completed_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="completed_quality_checklists",
        verbose_name=_("تکمیل‌کننده"),
    )

    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 = "pm"
        db_table = "pm_quality_checklist"
        verbose_name = _("چک‌لیست کیفیت")
        verbose_name_plural = _("چک‌لیست‌های کیفیت")
        ordering = ["-created_at"]

    def __str__(self):
        return self.name


class QualityChecklistItemModel(TenantAwareModel):
    """مدل ORM — آیتم چک‌لیست کیفیت."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    checklist = models.ForeignKey(
        QualityChecklistModel, on_delete=models.CASCADE,
        related_name="items", verbose_name=_("چک‌لیست"),
    )
    title = models.CharField(_("عنوان"), max_length=200)
    description = models.TextField(_("توضیحات"), blank=True)
    sort_order = models.IntegerField(_("ترتیب"), default=0)

    is_checked = models.BooleanField(_("بررسی‌شده"), default=False)
    checked_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="checked_quality_items",
        verbose_name=_("بررسی‌کننده"),
    )
    checked_date = models.DateField(_("تاریخ بررسی"), null=True, blank=True)
    result = models.CharField(_("نتیجه"), max_length=20, blank=True)
    remarks = models.TextField(_("ملاحظات"), blank=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_quality_checklist_item"
        verbose_name = _("آیتم چک‌لیست")
        verbose_name_plural = _("آیتم‌های چک‌لیست")
        ordering = ["sort_order"]

    def __str__(self):
        return self.title


# ═══════════════════════════════════════════════════
# Project Document — ارتباط اسناد با پروژه
# ═══════════════════════════════════════════════════

class ProjectDocumentModel(TenantAwareModel):
    """مدل ORM — ارتباط سند با پروژه/فعالیت."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(
        ProjectModel, on_delete=models.CASCADE,
        related_name="project_documents", verbose_name=_("پروژه"),
    )
    document_id = models.UUIDField(
        verbose_name=_("شناسه سند"),
        help_text=_("UUID سند از سرویس مدیریت اسناد"),
        db_index=True,
    )
    entity_type = models.CharField(
        _("نوع موجودیت"), max_length=50, default="project",
        help_text=_("نوع entity مرتبط: project, task, change_request"),
    )
    entity_id = models.UUIDField(
        _("شناسه موجودیت"), null=True, blank=True,
        help_text=_("UUID entity خاص در پروژه"),
    )
    title = models.CharField(_("عنوان سند"), max_length=500, blank=True, default="")
    document_code = models.CharField(_("کد سند"), max_length=100, blank=True, default="")
    linked_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name="linked_project_documents",
        verbose_name=_("پیوندکننده"),
    )
    notes = models.TextField(_("یادداشت"), blank=True, default="")

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "pm"
        db_table = "pm_project_document"
        verbose_name = _("سند پروژه")
        verbose_name_plural = _("اسناد پروژه")
        ordering = ["-created_at"]
        unique_together = [("project", "document_id")]

    def __str__(self):
        return f"{self.document_code} - {self.title}"
