from django.db import models

from apps.companies.models import Company
from apps.core.models import User
from django.utils import timezone
from coresite.mixin import AbstractTimeStampModel
from apps.calls.constants import BotType, CRON_JOB_STATUS


class Call(AbstractTimeStampModel):
    """Call object."""

    TRANSFER_STATUS_CHOICES = [
        (0, 'Not Transferred'),
        (1, 'Transferred'),
        (2, 'Transfer Failed'),
    ]

    BOOKING_INTENT_STATUS_CHOICES = [
        (CRON_JOB_STATUS['NOT_PROCESSED'], 'NOT_PROCESSED'),
        (CRON_JOB_STATUS['PROCESSING'], 'PROCESSING'),
        (CRON_JOB_STATUS['COMPLETED'], 'COMPLETED'),
        (CRON_JOB_STATUS['FAILED'], 'FAILED'),
    ]

    BOOKING_INTENT_CHOICES = [
        (0, 'No Intent for booking'),
        (1, 'Intent for booking'),
    ]
    CALL_TIME_CATEGORY_CHOICES = [
        (1, 'Ontime - call received during office hours'),
        (2, 'Offtime - call received after office hours'),
        (3, 'Holiday - call received during holiday'),
    ]
    BOT_TYPE_CHOICES = [
        (BotType.SALES_BOT.value, 'Sales Bot'),
        (BotType.SERVICE_BOT.value, 'Service Bot'),
    ]

    caller_name = models.CharField(max_length=255, blank=True, null=True)
    from_number = models.CharField(max_length=255)
    to_number = models.CharField(max_length=255)
    transfer_status = models.SmallIntegerField(
        choices=TRANSFER_STATUS_CHOICES,
        default=0
    )
    call_time_category = models.SmallIntegerField(null=True, choices=CALL_TIME_CATEGORY_CHOICES)
    transfer_number = models.CharField(max_length=255, blank=True, null=True)
    transfer_user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    company = models.ForeignKey(Company, on_delete=models.SET_NULL, null=True, blank=True)
    dealership = models.ForeignKey(
        'companies.Dealership',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="calls",
    )
    status = models.CharField(max_length=255)
    transcript = models.TextField(blank=True)
    transcript_complete = models.TextField(blank=True, null=True)
    summary = models.TextField(blank=True)
    bot_type = models.SmallIntegerField(null=True, choices=BOT_TYPE_CHOICES)
    sentiment = models.SmallIntegerField(null=True)
    duration = models.DecimalField(max_digits=5, decimal_places=2)
    cost = models.DecimalField(max_digits=5, decimal_places=2)
    call_id = models.CharField(max_length=255)
    twilio_call_sid = models.CharField(max_length=255)
    twilio_recording_text = models.TextField(blank=True, null=True)
    booking_datetime = models.DateTimeField(null=True, blank=True)
    booking_intent = models.SmallIntegerField(null=True, choices=BOOKING_INTENT_CHOICES)
    booking_intent_status = models.SmallIntegerField(null=True, choices=BOOKING_INTENT_STATUS_CHOICES)
    read_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name="read_calls")
    read_at = models.DateTimeField(null=True, blank=True)



class TonyCall(AbstractTimeStampModel):
    """Call object."""
    end_reason = models.CharField(max_length=255)
    call_id = models.CharField(max_length=255)
    recording_url = models.CharField(max_length=255)
    transcript = models.TextField(blank=True)
    call_date_time = models.DateTimeField(null=True, blank=True)
    intention = models.CharField(max_length=255)
    rescheduled  = models.CharField(max_length=255)
    booking_datetime = models.DateTimeField(null=True, blank=True)
    company = models.ForeignKey(Company, on_delete=models.SET_NULL, null=True, blank=True)
    status = models.CharField(max_length=255)
    called_to = models.CharField(max_length=255)
    called_number = models.CharField(max_length=255)

    class Meta:
        db_table = "vtony_calls"





class CallActivity(AbstractTimeStampModel):
    ACTION_CHOICES = [
        ('READ', 'read'),
        ('PLAY', 'played'),
    ]

    call = models.ForeignKey(Call, on_delete=models.CASCADE, related_name='activities')
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='call_activities')
    action = models.CharField(max_length=10, choices=ACTION_CHOICES)
    performed_at = models.DateTimeField(null=True)
    duration_played = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)

    class Meta:
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.user} {self.action.lower()} {self.call} at {self.created_at}"




class UserMessage(AbstractTimeStampModel):
    recipient = models.ForeignKey(
        User, 
        on_delete=models.CASCADE, 
        related_name='received_messages'
    )
    customer_name = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        help_text="Name of the customer who sent or is related to this message."
    )
    customer_number = models.CharField(
        max_length=20,
        blank=True,
        null=True,
        help_text="Customer phone number. Store as text to preserve formatting."
    )
    subject = models.CharField(max_length=255, blank=True)
    body = models.TextField()
    is_read = models.BooleanField(default=False)
    read_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        ordering = ['-created_at']

    def mark_as_read(self):
        if not self.is_read:
            self.is_read = True
            self.read_at = timezone.now()
            self.save(update_fields=['is_read', 'read_at'])

    def __str__(self):
        return f'''
        Message from {self.customer_name} to 
        {self.recipient.profile.full_name} 
        | Read: {self.is_read}
'''




class NotificationType(models.IntegerChoices):
    MISSED_CALL = 1, "Missed Call"
    MESSAGE = 2, "Message"




class Notification(models.Model):
    recipient = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name="notifications"
    )

    notification_type = models.SmallIntegerField(
        choices=NotificationType.choices,
        db_index=True
    )

    call = models.ForeignKey(
        Call,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="notifications",
        help_text="Optional reference to the call this notification is about"
    )

    title = models.CharField(max_length=255, blank=True, null=True)
    message = models.TextField(blank=True, null=True)

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

    created_at = models.DateTimeField(auto_now_add=True)

    def mark_as_read(self):
        if not self.is_read:
            self.is_read = True
            self.read_at = timezone.now()
            self.save(update_fields=["is_read", "read_at"])
    
    class Meta:
        indexes = [
            models.Index(fields=["recipient", "is_read"]),
            models.Index(fields=["recipient", "created_at"]),
        ]
        
        ordering = ['-created_at']

    def __str__(self):
        name = getattr(self.recipient.profile, "full_name", self.recipient.username)
        return f"Notification to {name} | Read: {self.is_read}"
