"""
Projects models - Quality Improvement (QI) projects tracking

This module implements QI project management:
- Project tracking
- Task management
- PDCA cycle phases
- Milestone tracking
- Outcome measurement
"""

from django.db import models
from django.utils.translation import gettext_lazy as _

from apps.core.models import StatusChoices, TimeStampedModel, UUIDModel


class PDCAPhaseChoices(models.TextChoices):
    PLAN = "plan", _("Plan")
    DO = "do", _("Do")
    CHECK = "check", _("Check")
    ACT = "act", _("Act")


class FOCUSPhaseChoices(models.TextChoices):
    FIND = "find", _("Find")
    ORGANIZE = "organize", _("Organize")
    CLARIFY = "clarify", _("Clarify")
    UNDERSTAND = "understand", _("Understand")
    SELECT = "select", _("Select")


class QIProject(UUIDModel, TimeStampedModel):
    """
    Quality Improvement Project.

    Tracks improvement initiatives driven by PX feedback.
    Can also serve as a template for creating new projects.
    """

    name = models.CharField(max_length=200)
    name_ar = models.CharField(max_length=200, blank=True)
    description = models.TextField()

    # Template flag - if True, this is a template not an active project
    is_template = models.BooleanField(
        default=False, db_index=True, help_text="If True, this is a reusable template, not an active project"
    )

    # Organization
    hospital = models.ForeignKey(
        "organizations.Hospital",
        on_delete=models.CASCADE,
        related_name="qi_projects",
        null=True,
        blank=True,
        help_text="Null for global templates available to all hospitals",
    )
    department = models.ForeignKey(
        "organizations.Department", on_delete=models.SET_NULL, null=True, blank=True, related_name="qi_projects"
    )

    # Project lead
    project_lead = models.ForeignKey("accounts.User", on_delete=models.SET_NULL, null=True, related_name="led_projects")

    # Creator
    created_by = models.ForeignKey(
        "accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="created_qi_projects"
    )

    # Team members
    team_members = models.ManyToManyField("accounts.User", blank=True, related_name="qi_projects")

    # Status
    status = models.CharField(
        max_length=20, choices=StatusChoices.choices, default=StatusChoices.PENDING, db_index=True
    )

    # Dates
    start_date = models.DateField(null=True, blank=True)
    target_completion_date = models.DateField(null=True, blank=True, db_index=True)
    actual_completion_date = models.DateField(null=True, blank=True)

    # Linked to PX Actions (optional)
    related_actions = models.ManyToManyField("px_action_center.PXAction", blank=True, related_name="qi_projects")

    # Outcomes
    outcome_description = models.TextField(blank=True)
    success_metrics = models.JSONField(default=dict, blank=True, help_text="Success metrics and results")

    # FOCUS methodology
    focus_enabled = models.BooleanField(
        default=True, help_text="Whether to use FOCUS methodology alongside PDCA"
    )

    # Metadata
    metadata = models.JSONField(default=dict, blank=True)

    class Meta:
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["hospital", "status", "-created_at"]),
            models.Index(fields=["is_template", "hospital"]),
            models.Index(fields=["project_lead", "status"]),
            models.Index(fields=["status", "target_completion_date"]),
        ]

    def __str__(self):
        if self.is_template:
            return f"[Template] {self.name}"
        return f"{self.name} ({self.status})"


class QIProjectTask(UUIDModel, TimeStampedModel):
    """
    Task within a QI project.
    """

    project = models.ForeignKey(QIProject, on_delete=models.CASCADE, related_name="tasks")
    pdca_phase = models.ForeignKey(
        "PDCAPhase",
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name="tasks",
    )
    focus_phase = models.ForeignKey(
        "FOCUSPhase",
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name="tasks",
    )

    title = models.CharField(max_length=500)
    description = models.TextField(blank=True)

    # Assignment
    assigned_to = models.ForeignKey(
        "accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="qi_tasks"
    )

    # Status
    status = models.CharField(max_length=20, choices=StatusChoices.choices, default=StatusChoices.PENDING)

    # Dates
    due_date = models.DateField(null=True, blank=True)
    completed_date = models.DateField(null=True, blank=True)

    # Order
    order = models.IntegerField(default=0)

    class Meta:
        ordering = ["project", "order"]

    def __str__(self):
        return f"{self.project.name} - {self.title}"


class PDCAPhase(UUIDModel, TimeStampedModel):
    """
    PDCA (Plan-Do-Check-Act) phase within a QI project.
    Each project can have up to 4 phases, one per PDCA stage.
    """

    project = models.ForeignKey(QIProject, on_delete=models.CASCADE, related_name="pdca_phases")
    phase = models.CharField(max_length=10, choices=PDCAPhaseChoices.choices)

    title = models.CharField(max_length=300, blank=True)
    description = models.TextField(blank=True)

    owner = models.ForeignKey(
        "accounts.User",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="owned_pdca_phases",
    )

    status = models.CharField(max_length=20, choices=StatusChoices.choices, default=StatusChoices.PENDING)

    start_date = models.DateField(null=True, blank=True)
    due_date = models.DateField(null=True, blank=True)
    completed_date = models.DateField(null=True, blank=True)

    findings = models.TextField(blank=True)

    order = models.IntegerField(default=0)

    class Meta:
        unique_together = [("project", "phase")]
        ordering = ["project", "order"]

    def __str__(self):
        return f"{self.project.name} - {self.get_phase_display()}"


class FOCUSPhase(UUIDModel, TimeStampedModel):
    """
    FOCUS (Find, Organize, Clarify, Understand, Select) phase within a QI project.
    Each project can have up to 5 phases, one per FOCUS stage.
    """

    project = models.ForeignKey(QIProject, on_delete=models.CASCADE, related_name="focus_phases")
    phase = models.CharField(max_length=15, choices=FOCUSPhaseChoices.choices)

    title = models.CharField(max_length=300, blank=True)
    description = models.TextField(blank=True)

    owner = models.ForeignKey(
        "accounts.User",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="owned_focus_phases",
    )

    status = models.CharField(max_length=20, choices=StatusChoices.choices, default=StatusChoices.PENDING)

    start_date = models.DateField(null=True, blank=True)
    due_date = models.DateField(null=True, blank=True)
    completed_date = models.DateField(null=True, blank=True)

    findings = models.TextField(blank=True)

    order = models.IntegerField(default=0)

    class Meta:
        unique_together = [("project", "phase")]
        ordering = ["project", "order"]

    def __str__(self):
        return f"{self.project.name} - {self.get_phase_display()}"
