import uuid
from django.db import models
from django.utils import timezone

from coresite.mixin import AbstractTimeStampModel
from apps.calls.models import Call
from apps.calls.constants import BotType
from apps.companies.models import Company


class Appointment(AbstractTimeStampModel):
    name = models.CharField(max_length=255)
    scheduled_date = models.DateTimeField()
    offtime = models.SmallIntegerField(null=True, blank=True)
    appointment_phone = models.CharField(
        max_length=255,
        null=True, blank=True
    )  # Phone number of the appointment i.e. appointment is booked against this number rather than actual calling number of the person
    bot_type = models.SmallIntegerField(
        null=True,
        choices=BotType.model_choices()
    )
    booking_type = models.CharField(
        max_length=150,
        null=True,
        blank=True,
        db_index=True,
        help_text="Type of appointment booking"
    )
    call = models.ForeignKey(
        Call,
        on_delete=models.SET_NULL,
        null=True, blank=True
    )
    company = models.ForeignKey(
        Company,
        on_delete=models.SET_NULL,
        null=True, blank=True
    )
    twilio_call_sid = models.CharField(max_length=255)

    def __str__(self):
        booking = self.booking_type if self.booking_type else "Unknown"
        return (
            f"Appointment {self.id} - {self.name} "
            f"on {self.scheduled_date:%Y-%m-%d %H:%M} "
            f"({booking})"
        )


class WebhookEvent(models.Model):
    """
    Stores every incoming webhook exactly as received for audit, debugging,
    replay and analytics.
    """
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        editable=False
    )

    source = models.CharField(max_length=50)
    event_type = models.CharField(max_length=100, db_index=True)

    headers = models.JSONField(null=True, blank=True)
    raw_payload = models.JSONField()

    processed = models.BooleanField(default=False)
    processed_at = models.DateTimeField(null=True, blank=True)

    success = models.BooleanField(null=True)
    error_message = models.TextField(null=True, blank=True)

    received_at = models.DateTimeField(default=timezone.now, db_index=True)

    class Meta:
        ordering = ["-received_at"]
        verbose_name_plural = "Webhook Event"
        indexes = [
            models.Index(fields=["source", "event_type"]),
            models.Index(fields=["processed"]),
        ]

    def mark_success(self):
        self.processed = True
        self.success = True
        self.processed_at = timezone.now()
        self.save(update_fields=["processed", "success", "processed_at"])

    def mark_failed(self, error):
        self.processed = True
        self.success = False
        self.error_message = str(error)
        self.processed_at = timezone.now()
        self.save(update_fields=["processed", "success", "error_message", "processed_at"])


class FeatureFlag(models.Model):
    key = models.CharField(max_length=100, unique=True)
    enabled = models.BooleanField(default=False)

    def __str__(self):
        return f"{self.key}: {'ON' if self.enabled else 'OFF'}"

    class Meta:
        verbose_name_plural = "Feature Flags"


class OutboundMessage(models.Model):
    # Possible Choices

    # CHANNEL_CHOICES = (
    #     ("sms", "SMS"),
    #     ("email", "Email"),
    # )
    #
    # STATUS_CHOICES = (
    #     ("pending", "Pending"),
    #     ("sent", "Sent"),
    #     ("failed", "Failed"),
    #     ("delivered", "Delivered"),
    # )

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    channel = models.CharField(max_length=10)
    to = models.TextField()
    subject = models.TextField(null=True, blank=True)

    template_name = models.TextField(null=True, blank=True)
    context = models.JSONField(null=True, blank=True)
    message_payload = models.JSONField(null=True, blank=True)

    provider_message_id = models.TextField(null=True, blank=True)
    twilio_call_sid = models.TextField(null=True, blank=True)
    retell_call_id = models.TextField(null=True, blank=True)

    status = models.CharField(max_length=20, default="pending")

    error_message = models.TextField(null=True, blank=True)

    created_at = models.DateTimeField(auto_now_add=True)
    sent_at = models.DateTimeField(null=True, blank=True)
    delivered_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        indexes = [
            models.Index(fields=["channel", "status"]),
            models.Index(fields=["provider_message_id"]),
        ]
