"""
RCA (Root Cause Analysis) models

This module implements the Root Cause Analysis system that:
- Tracks RCAs for complaints, inquiries, observations, and feedback
- Manages root causes and contributing factors
- Tracks corrective actions and their effectiveness
- Maintains audit trail with notes and status changes
- Supports attachments and documentation
"""

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.utils import timezone

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


class RCAStatus(models.TextChoices):
    """RCA status choices"""

    DRAFT = "draft", "Draft"
    IN_PROGRESS = "in_progress", "In Progress"
    REVIEW = "review", "Under Review"
    APPROVED = "approved", "Approved"
    CLOSED = "closed", "Closed"


class RCASeverity(models.TextChoices):
    """RCA severity choices"""

    LOW = "low", "Low"
    MEDIUM = "medium", "Medium"
    HIGH = "high", "High"
    CRITICAL = "critical", "Critical"


class RCAActionType(models.TextChoices):
    """Corrective action type choices"""

    PREVENTIVE = "preventive", "Preventive"
    CORRECTIVE = "corrective", "Corrective"
    IMMEDIATE = "immediate", "Immediate Action"
    LONG_TERM = "long_term", "Long-term Solution"


class RCAActionStatus(models.TextChoices):
    """Corrective action status choices"""

    NOT_STARTED = "not_started", "Not Started"
    IN_PROGRESS = "in_progress", "In Progress"
    COMPLETED = "completed", "Completed"
    CANCELLED = "cancelled", "Cancelled"


class RootCauseCategory(models.TextChoices):
    """Root cause category choices"""

    PROCESS = "process", "Process/Procedure"
    PEOPLE = "people", "People/Training"
    EQUIPMENT = "equipment", "Equipment/Resources"
    COMMUNICATION = "communication", "Communication"
    POLICY = "policy", "Policy/Regulation"
    ENVIRONMENT = "environment", "Environment"
    TECHNOLOGY = "technology", "Technology/Systems"
    OTHER = "other", "Other"


class RootCauseAnalysis(UUIDModel, TimeStampedModel):
    """
    Root Cause Analysis model.

    Links to complaints, inquiries, observations, or feedback via GenericForeignKey.
    Tracks the complete RCA process from creation to closure.
    """

    # Related item (can be Complaint, Inquiry, Observation, or Feedback)
    content_type = models.ForeignKey(
        ContentType,
        on_delete=models.PROTECT,
        related_name="related_rcas",
        help_text="Type of the related item",
        null=True,
        blank=True,
    )
    object_id = models.UUIDField(db_index=True, null=True, blank=True, help_text="ID of the related item")
    related_item = GenericForeignKey("content_type", "object_id")

    # Organization
    hospital = models.ForeignKey("organizations.Hospital", on_delete=models.CASCADE, related_name="rcas")
    department = models.ForeignKey(
        "organizations.Department", on_delete=models.SET_NULL, null=True, blank=True, related_name="rcas"
    )

    # RCA details
    title = models.CharField(max_length=500)
    description = models.TextField(help_text="Description of the incident/issue")
    background = models.TextField(blank=True, help_text="Background information and context")

    # Status and severity
    status = models.CharField(max_length=20, choices=RCAStatus.choices, default=RCAStatus.DRAFT, db_index=True)
    severity = models.CharField(max_length=20, choices=RCASeverity.choices, default=RCASeverity.MEDIUM, db_index=True)

    # Priority
    priority = models.CharField(
        max_length=20, choices=PriorityChoices.choices, default=PriorityChoices.MEDIUM, db_index=True
    )

    # Root cause analysis summary
    root_cause_summary = models.TextField(blank=True, help_text="Summary of root cause analysis findings")

    # Assignment
    assigned_to = models.ForeignKey(
        "accounts.User",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="assigned_rcas",
        help_text="Person responsible for RCA",
    )
    assigned_at = models.DateTimeField(null=True, blank=True)

    # Created by
    created_by = models.ForeignKey(
        "accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="created_rcas"
    )

    # Approval
    approved_by = models.ForeignKey(
        "accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="rca_approved_items"
    )
    approved_at = models.DateTimeField(null=True, blank=True)
    approval_notes = models.TextField(blank=True)

    # Closure
    closed_by = models.ForeignKey(
        "accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="closed_rcas"
    )
    closed_at = models.DateTimeField(null=True, blank=True)
    closure_notes = models.TextField(blank=True)

    # Dates
    target_completion_date = models.DateField(null=True, blank=True, help_text="Target date for RCA completion")
    actual_completion_date = models.DateField(null=True, blank=True)

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

    # Soft delete
    is_deleted = models.BooleanField(default=False, db_index=True)
    deleted_at = models.DateTimeField(null=True, blank=True)
    deleted_by = models.ForeignKey(
        "accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="deleted_rcas"
    )

    class Meta:
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["status", "-created_at"]),
            models.Index(fields=["hospital", "status", "-created_at"]),
            models.Index(fields=["department", "status", "-created_at"]),
            models.Index(fields=["assigned_to", "status", "-created_at"]),
            models.Index(fields=["is_deleted", "-created_at"]),
            models.Index(fields=["content_type", "object_id"]),
        ]
        verbose_name = "Root Cause Analysis"
        verbose_name_plural = "Root Cause Analyses"

    def __str__(self):
        return f"{self.title} ({self.get_status_display()})"

    def get_related_item_type(self):
        """Get the type of related item"""
        if self.content_type:
            return self.content_type.model
        return None

    def get_related_item_display(self):
        """Get display name of related item"""
        try:
            return str(self.related_item)
        except Exception:
            return f"Item {self.object_id}"

    def get_related_item_url(self):
        """Get URL for the related item"""
        if not self.content_type or not self.object_id:
            return None
        try:
            obj = self.related_item
            if obj and hasattr(obj, "get_absolute_url"):
                return obj.get_absolute_url()
        except Exception:
            pass
        return None

    def get_root_causes_count(self):
        """Get count of root causes"""
        return self.root_causes.count()

    def get_corrective_actions_count(self):
        """Get count of corrective actions"""
        return self.corrective_actions.count()

    def get_completed_actions_count(self):
        """Get count of completed corrective actions"""
        return self.corrective_actions.filter(status=RCAActionStatus.COMPLETED).count()

    def soft_delete(self, user=None):
        """Soft delete RCA"""
        self.is_deleted = True
        self.deleted_at = timezone.now()
        self.deleted_by = user
        self.save(update_fields=["is_deleted", "deleted_at", "deleted_by"])


class RCARootCause(UUIDModel, TimeStampedModel):
    """
    Individual root cause identified in an RCA.

    Multiple root causes can be identified per RCA.
    """

    rca = models.ForeignKey(RootCauseAnalysis, on_delete=models.CASCADE, related_name="root_causes")

    # Root cause details
    description = models.TextField(help_text="Description of root cause")
    category = models.CharField(max_length=50, choices=RootCauseCategory.choices, db_index=True)

    # Contributing factors
    contributing_factors = models.TextField(blank=True, help_text="Factors that contributed to this root cause")

    # Impact assessment
    likelihood = models.IntegerField(null=True, blank=True, help_text="Likelihood score (1-5)")
    impact = models.IntegerField(null=True, blank=True, help_text="Impact score (1-5)")
    risk_score = models.IntegerField(null=True, blank=True, help_text="Risk score (likelihood * impact)")

    # Evidence
    evidence = models.TextField(blank=True, help_text="Evidence supporting this root cause")

    # Verification
    is_verified = models.BooleanField(default=False)
    verified_by = models.ForeignKey(
        "accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="verified_root_causes"
    )
    verified_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["rca", "-created_at"]),
            models.Index(fields=["category", "-created_at"]),
        ]
        verbose_name = "Root Cause"
        verbose_name_plural = "Root Causes"

    def __str__(self):
        return f"{self.rca.title} - {self.description[:50]}"

    def save(self, *args, **kwargs):
        """Calculate risk score before saving"""
        if self.likelihood and self.impact:
            self.risk_score = self.likelihood * self.impact
        super().save(*args, **kwargs)


class RCACorrectiveAction(UUIDModel, TimeStampedModel):
    """
    Corrective action to address identified root causes.

    Each action is tracked for completion and effectiveness.
    """

    rca = models.ForeignKey(RootCauseAnalysis, on_delete=models.CASCADE, related_name="corrective_actions")
    root_cause = models.ForeignKey(
        RCARootCause,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="corrective_actions",
        help_text="Root cause this action addresses",
    )

    # Action details
    description = models.TextField(help_text="Description of corrective action")
    action_type = models.CharField(
        max_length=20, choices=RCAActionType.choices, default=RCAActionType.CORRECTIVE, db_index=True
    )

    # Responsibility
    responsible_person = models.ForeignKey(
        "organizations.Staff",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="corrective_actions",
        help_text="Person responsible for implementing the action",
    )

    # Dates
    target_date = models.DateField(null=True, blank=True, help_text="Target date for completion")
    completion_date = models.DateField(null=True, blank=True, help_text="Actual completion date")

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

    # Effectiveness
    effectiveness_measure = models.TextField(blank=True, help_text="How effectiveness will be measured")
    effectiveness_assessment = models.TextField(blank=True, help_text="Assessment of action effectiveness")
    effectiveness_score = models.IntegerField(null=True, blank=True, help_text="Effectiveness score (1-5)")

    # Obstacles
    obstacles = models.TextField(blank=True, help_text="Obstacles encountered during implementation")

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

    class Meta:
        ordering = ["target_date", "-created_at"]
        indexes = [
            models.Index(fields=["rca", "-created_at"]),
            models.Index(fields=["status", "target_date"]),
            models.Index(fields=["action_type", "-created_at"]),
        ]
        verbose_name = "Corrective Action"
        verbose_name_plural = "Corrective Actions"

    def __str__(self):
        return f"{self.description[:50]} - {self.get_status_display()}"


class RCAAttachment(UUIDModel, TimeStampedModel):
    """Attachments for RCA documentation"""

    rca = models.ForeignKey(RootCauseAnalysis, on_delete=models.CASCADE, related_name="attachments")

    file = models.FileField(upload_to="rca/%Y/%m/%d/")
    filename = models.CharField(max_length=500)
    file_type = models.CharField(max_length=100, blank=True)
    file_size = models.IntegerField(help_text="File size in bytes")

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

    description = models.TextField(blank=True)

    class Meta:
        ordering = ["-created_at"]
        verbose_name = "RCA Attachment"
        verbose_name_plural = "RCA Attachments"

    def __str__(self):
        return f"{self.rca.title} - {self.filename}"


class RCANote(UUIDModel, TimeStampedModel):
    """Internal notes for RCA"""

    rca = models.ForeignKey(RootCauseAnalysis, on_delete=models.CASCADE, related_name="notes")

    note = models.TextField()
    created_by = models.ForeignKey(
        "accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="rca_notes"
    )

    is_internal = models.BooleanField(default=True, help_text="Internal note (not visible in reports)")

    class Meta:
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["rca", "-created_at"]),
        ]
        verbose_name = "RCA Note"
        verbose_name_plural = "RCA Notes"

    def __str__(self):
        return f"{self.rca.title} - {self.created_at.strftime('%Y-%m-%d %H:%M')}"


class RCAStatusLog(UUIDModel, TimeStampedModel):
    """Audit trail for RCA status changes"""

    rca = models.ForeignKey(RootCauseAnalysis, on_delete=models.CASCADE, related_name="status_logs")

    old_status = models.CharField(max_length=20, blank=True)
    new_status = models.CharField(max_length=20, db_index=True)

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

    notes = models.TextField(blank=True)
    metadata = models.JSONField(default=dict, blank=True)

    class Meta:
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["rca", "-created_at"]),
            models.Index(fields=["new_status", "-created_at"]),
        ]
        verbose_name = "RCA Status Log"
        verbose_name_plural = "RCA Status Logs"

    def __str__(self):
        return f"{self.rca.title}: {self.old_status} → {self.new_status}"
