"""
Feedback models - Patient feedback and suggestions management

This module implements the feedback management system that:
- Tracks patient feedback (compliments, suggestions, general feedback)
- Manages feedback workflow (submitted → reviewed → acknowledged → closed)
- Maintains feedback responses and timeline
- Supports attachments and ratings
"""
from django.conf import settings
from django.db import models
from django.utils import timezone

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


class FeedbackType(models.TextChoices):
    """Feedback type choices"""
    COMPLIMENT = 'compliment', 'Compliment'
    SUGGESTION = 'suggestion', 'Suggestion'
    GENERAL = 'general', 'General Feedback'
    INQUIRY = 'inquiry', 'Inquiry'
    SATISFACTION_CHECK = 'satisfaction_check', 'Satisfaction Check'


class FeedbackStatus(models.TextChoices):
    """Feedback status choices"""
    SUBMITTED = 'submitted', 'Submitted'
    REVIEWED = 'reviewed', 'Reviewed'
    ACKNOWLEDGED = 'acknowledged', 'Acknowledged'
    CLOSED = 'closed', 'Closed'


class FeedbackCategory(models.TextChoices):
    """Feedback category choices"""
    CLINICAL_CARE = 'clinical_care', 'Clinical Care'
    STAFF_SERVICE = 'staff_service', 'Staff Service'
    FACILITY = 'facility', 'Facility & Environment'
    COMMUNICATION = 'communication', 'Communication'
    APPOINTMENT = 'appointment', 'Appointment & Scheduling'
    BILLING = 'billing', 'Billing & Insurance'
    FOOD_SERVICE = 'food_service', 'Food Service'
    CLEANLINESS = 'cleanliness', 'Cleanliness'
    TECHNOLOGY = 'technology', 'Technology & Systems'
    OTHER = 'other', 'Other'


class SentimentChoices(models.TextChoices):
    """Sentiment analysis choices"""
    POSITIVE = 'positive', 'Positive'
    NEUTRAL = 'neutral', 'Neutral'
    NEGATIVE = 'negative', 'Negative'


class Feedback(UUIDModel, TimeStampedModel):
    """
    Feedback model for patient feedback, compliments, and suggestions.

    Workflow:
    1. SUBMITTED - Feedback received
    2. REVIEWED - Being reviewed by staff
    3. ACKNOWLEDGED - Response provided
    4. CLOSED - Feedback closed
    """
    # Patient and encounter information
    patient = models.ForeignKey(
        'organizations.Patient',
        on_delete=models.CASCADE,
        related_name='feedbacks',
        null=True,
        blank=True,
        help_text="Patient who provided feedback (optional for anonymous feedback)"
    )

    # Anonymous feedback support
    is_anonymous = models.BooleanField(default=False)
    contact_name = models.CharField(max_length=200, blank=True)
    contact_email = models.EmailField(blank=True)
    contact_phone = models.CharField(max_length=20, blank=True)

    encounter_id = models.CharField(
        max_length=100,
        blank=True,
        db_index=True,
        help_text="Related encounter ID if applicable"
    )

    # Survey linkage (for satisfaction checks after negative surveys)
    related_survey = models.ForeignKey(
        'surveys.SurveyInstance',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='follow_up_feedbacks',
        help_text="Survey that triggered this satisfaction check feedback"
    )

    # Organization
    hospital = models.ForeignKey(
        'organizations.Hospital',
        on_delete=models.CASCADE,
        related_name='feedbacks'
    )
    department = models.ForeignKey(
        'organizations.Department',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='feedbacks'
    )
    staff = models.ForeignKey(
        'organizations.Staff',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='feedbacks',
        help_text="Staff member being mentioned in feedback"
    )

    # Feedback details
    feedback_type = models.CharField(
        max_length=20,
        choices=FeedbackType.choices,
        default=FeedbackType.GENERAL,
        db_index=True
    )

    title = models.CharField(max_length=500)
    message = models.TextField(help_text="Feedback message")

    # Classification
    category = models.CharField(
        max_length=50,
        choices=FeedbackCategory.choices,
        db_index=True
    )
    subcategory = models.CharField(max_length=100, blank=True)

    # Rating (1-5 stars)
    rating = models.IntegerField(
        null=True,
        blank=True,
        help_text="Rating from 1 to 5 stars"
    )

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

    # Sentiment analysis
    sentiment = models.CharField(
        max_length=20,
        choices=SentimentChoices.choices,
        default=SentimentChoices.NEUTRAL,
        db_index=True,
        help_text="Sentiment analysis result"
    )
    sentiment_score = models.FloatField(
        null=True,
        blank=True,
        help_text="Sentiment score from -1 (negative) to 1 (positive)"
    )

    # Status and workflow
    status = models.CharField(
        max_length=20,
        choices=FeedbackStatus.choices,
        default=FeedbackStatus.SUBMITTED,
        db_index=True
    )

    # Assignment
    assigned_to = models.ForeignKey(
        'accounts.User',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='assigned_feedbacks'
    )
    assigned_at = models.DateTimeField(null=True, blank=True)

    # Review tracking
    reviewed_at = models.DateTimeField(null=True, blank=True)
    reviewed_by = models.ForeignKey(
        'accounts.User',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='reviewed_feedbacks'
    )

    # Acknowledgment
    acknowledged_at = models.DateTimeField(null=True, blank=True)
    acknowledged_by = models.ForeignKey(
        'accounts.User',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='acknowledged_feedbacks'
    )

    # Closure
    closed_at = models.DateTimeField(null=True, blank=True)
    closed_by = models.ForeignKey(
        'accounts.User',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='closed_feedbacks'
    )

    # Flags
    is_featured = models.BooleanField(
        default=False,
        help_text="Feature this feedback (e.g., for testimonials)"
    )
    is_public = models.BooleanField(
        default=False,
        help_text="Make this feedback public"
    )
    requires_follow_up = models.BooleanField(default=False)
    
    # Source
    source = models.ForeignKey(
        'px_sources.PXSource',
        on_delete=models.PROTECT,
        related_name='feedbacks',
        null=True,
        blank=True,
        help_text="Source of feedback"
    )
    
    # 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_feedbacks'
    )

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['status', '-created_at']),
            models.Index(fields=['hospital', 'status', '-created_at']),
            models.Index(fields=['feedback_type', '-created_at']),
            models.Index(fields=['sentiment', '-created_at']),
            models.Index(fields=['is_deleted', '-created_at']),
        ]
        verbose_name_plural = 'Feedback'

    def __str__(self):
        if self.patient:
            return f"{self.title} - {self.patient.get_full_name()} ({self.feedback_type})"
        return f"{self.title} - Anonymous ({self.feedback_type})"

    def get_contact_name(self):
        """Get contact name (patient or anonymous)"""
        if self.patient:
            return self.patient.get_full_name()
        return self.contact_name or "Anonymous"

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


class FeedbackAttachment(UUIDModel, TimeStampedModel):
    """Feedback attachment (images, documents, etc.)"""
    feedback = models.ForeignKey(
        Feedback,
        on_delete=models.CASCADE,
        related_name='attachments'
    )

    file = models.FileField(upload_to='feedback/%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='feedback_attachments'
    )

    description = models.TextField(blank=True)

    class Meta:
        ordering = ['-created_at']

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


class FeedbackResponse(UUIDModel, TimeStampedModel):
    """
    Feedback response/timeline entry.

    Tracks all responses, status changes, and communications.
    """
    feedback = models.ForeignKey(
        Feedback,
        on_delete=models.CASCADE,
        related_name='responses'
    )

    # Response details
    response_type = models.CharField(
        max_length=50,
        choices=[
            ('status_change', 'Status Change'),
            ('assignment', 'Assignment'),
            ('note', 'Internal Note'),
            ('response', 'Response to Patient'),
            ('acknowledgment', 'Acknowledgment'),
        ],
        db_index=True
    )

    message = models.TextField()

    # User who made the response
    created_by = models.ForeignKey(
        'accounts.User',
        on_delete=models.SET_NULL,
        null=True,
        related_name='feedback_responses'
    )

    # Status change tracking
    old_status = models.CharField(max_length=20, blank=True)
    new_status = models.CharField(max_length=20, blank=True)

    # Visibility
    is_internal = models.BooleanField(
        default=False,
        help_text="Internal note (not visible to patient)"
    )

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

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['feedback', '-created_at']),
        ]

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