from django.db import models
from django.conf import settings
from django.core.validators import RegexValidator


class CommunicationSession(models.Model):
    """
    Masked communication session using Twilio Conversations.
    
    Enables staff and customers to communicate via SMS/chat without
    exposing personal phone numbers. Twilio routes messages through
    a proxy number.
    """
    
    # Link to event
    event = models.OneToOneField(
        'schedule.Event',
        on_delete=models.CASCADE,
        related_name='communication_session'
    )
    
    # Twilio identifiers
    twilio_conversation_sid = models.CharField(
        max_length=255,
        unique=True,
        db_index=True,
        help_text="Twilio Conversation SID"
    )
    
    # Session status
    is_active = models.BooleanField(
        default=True,
        db_index=True,
        help_text="Whether the conversation is active"
    )
    
    # Phone validation regex (E.164 format)
    phone_regex = RegexValidator(
        regex=r'^\+?1?\d{9,15}$',
        message="Phone number must be in E.164 format (+1234567890)"
    )
    
    # Secure phone storage
    # NOTE: In production, consider encrypting these fields
    staff_phone = models.CharField(
        max_length=20,
        validators=[phone_regex],
        help_text="Staff member's phone number (E.164 format)"
    )
    
    customer_phone = models.CharField(
        max_length=20,
        validators=[phone_regex],
        help_text="Customer's phone number (E.164 format)"
    )
    
    #  Localization
    language_code = models.CharField(
        max_length=10,
        default='en',
        help_text="Language preference for SMS templates (en/es/fr/de)"
    )
    
    # Participant SIDs (for cleanup)
    staff_participant_sid = models.CharField(
        max_length=255,
        blank=True,
        help_text="Twilio Participant SID for staff"
    )
    
    customer_participant_sid = models.CharField(
        max_length=255,
        blank=True,
        help_text="Twilio Participant SID for customer"
    )
    
    # Metadata
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    closed_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text="When the conversation was closed"
    )
    
    class Meta:
        app_label = 'messaging'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['is_active', 'created_at']),
        ]
    
    def __str__(self):
        status = "Active" if self.is_active else "Closed"
        return f"Session for {self.event.title} ({status})"
    
    @property
    def message_count(self):
        """
        Get total message count (would require Twilio API call).
        Stub for future implementation.
        """
        # TODO: Implement via Twilio API
        return None


class BroadcastMessage(models.Model):
    """
    Broadcast message sent by owners/managers to groups of users.

    Allows targeting specific role groups (owners, managers, staff, customers)
    or individual users within those groups.
    """

    class TargetType(models.TextChoices):
        ALL_OWNERS = 'all_owners', 'All Owners'
        ALL_MANAGERS = 'all_managers', 'All Managers'
        ALL_STAFF = 'all_staff', 'All Staff'
        ALL_CUSTOMERS = 'all_customers', 'All Customers'
        SELECTED_USERS = 'selected_users', 'Selected Users'

    class DeliveryMethod(models.TextChoices):
        IN_APP = 'in_app', 'In-App Notification'
        EMAIL = 'email', 'Email'
        SMS = 'sms', 'SMS'
        ALL = 'all', 'All Channels'

    class Status(models.TextChoices):
        DRAFT = 'draft', 'Draft'
        SCHEDULED = 'scheduled', 'Scheduled'
        SENDING = 'sending', 'Sending'
        SENT = 'sent', 'Sent'
        FAILED = 'failed', 'Failed'

    # Sender
    sender = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        related_name='sent_broadcast_messages',
        help_text="User who sent the message"
    )

    # Message content
    subject = models.CharField(
        max_length=255,
        help_text="Message subject (for email) or title (for in-app)"
    )
    body = models.TextField(
        help_text="Message body content"
    )

    # Targeting - can select multiple target types
    target_owners = models.BooleanField(
        default=False,
        help_text="Send to all owners"
    )
    target_managers = models.BooleanField(
        default=False,
        help_text="Send to all managers"
    )
    target_staff = models.BooleanField(
        default=False,
        help_text="Send to all staff"
    )
    target_customers = models.BooleanField(
        default=False,
        help_text="Send to all customers"
    )

    # Individual recipients (for selected_users mode)
    individual_recipients = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        blank=True,
        related_name='received_broadcast_messages',
        help_text="Specific users to receive the message"
    )

    # Delivery settings
    delivery_method = models.CharField(
        max_length=20,
        choices=DeliveryMethod.choices,
        default=DeliveryMethod.IN_APP,
        help_text="How to deliver the message"
    )

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

    # Scheduling
    scheduled_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text="When to send the message (null = send immediately)"
    )

    # Statistics
    total_recipients = models.PositiveIntegerField(
        default=0,
        help_text="Total number of recipients"
    )
    delivered_count = models.PositiveIntegerField(
        default=0,
        help_text="Number of successful deliveries"
    )
    failed_count = models.PositiveIntegerField(
        default=0,
        help_text="Number of failed deliveries"
    )
    read_count = models.PositiveIntegerField(
        default=0,
        help_text="Number of recipients who read the message"
    )

    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    sent_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text="When the message was actually sent"
    )

    class Meta:
        app_label = 'messaging'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['status', 'scheduled_at']),
            models.Index(fields=['sender', 'created_at']),
        ]

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

    def get_target_description(self):
        """Get human-readable description of targets."""
        targets = []
        if self.target_owners:
            targets.append('Owners')
        if self.target_managers:
            targets.append('Managers')
        if self.target_staff:
            targets.append('Staff')
        if self.target_customers:
            targets.append('Customers')
        if self.individual_recipients.exists():
            count = self.individual_recipients.count()
            targets.append(f'{count} Individual(s)')
        return ', '.join(targets) if targets else 'No recipients'


class MessageRecipient(models.Model):
    """
    Tracks individual message delivery status for each recipient.
    """

    class DeliveryStatus(models.TextChoices):
        PENDING = 'pending', 'Pending'
        DELIVERED = 'delivered', 'Delivered'
        FAILED = 'failed', 'Failed'
        BOUNCED = 'bounced', 'Bounced'

    message = models.ForeignKey(
        BroadcastMessage,
        on_delete=models.CASCADE,
        related_name='recipients'
    )

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='message_deliveries'
    )

    # Delivery tracking
    delivery_status = models.CharField(
        max_length=20,
        choices=DeliveryStatus.choices,
        default=DeliveryStatus.PENDING
    )
    delivered_at = models.DateTimeField(null=True, blank=True)

    # Read tracking
    is_read = models.BooleanField(default=False)
    read_at = models.DateTimeField(null=True, blank=True)

    # Error tracking
    error_message = models.TextField(blank=True)

    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        app_label = 'messaging'
        unique_together = ['message', 'user']
        indexes = [
            models.Index(fields=['message', 'delivery_status']),
            models.Index(fields=['user', 'is_read']),
        ]

    def __str__(self):
        return f"{self.message.subject} -> {self.user.email}"
