"""
Eventos de entrega notificados por los proveedores.

Sirve tanto para el webhook de eventos de SendGrid como, mas adelante, para
los callbacks de estado de Twilio: la estructura es la misma y lo unico que
cambia es quien los manda.

El proveedor puede reenviar el mismo evento varias veces (reintentos ante un
5xx o un tiempo de espera agotado), por eso `provider_event_id` es unico: la
insercion duplicada la descarta la base de datos.
"""

from __future__ import annotations

from django.db import models


class EventType(models.TextChoices):
    """Eventos de SendGrid que se registran."""

    PROCESSED = "processed", "Procesado"
    DEFERRED = "deferred", "Diferido"
    DELIVERED = "delivered", "Entregado"
    OPEN = "open", "Abierto"
    CLICK = "click", "Clic"
    BOUNCE = "bounce", "Rebotado"
    DROPPED = "dropped", "Descartado"
    SPAM_REPORT = "spamreport", "Reportado como spam"
    UNSUBSCRIBE = "unsubscribe", "Baja"
    GROUP_UNSUBSCRIBE = "group_unsubscribe", "Baja de grupo"
    GROUP_RESUBSCRIBE = "group_resubscribe", "Alta de grupo"


class NotificationEvent(models.Model):
    """Un evento recibido por webhook, asociado a un envio cuando se puede."""

    message = models.ForeignKey(
        "notifications.NotificationMessage",
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name="events",
        verbose_name="Notificación",
        help_text="Envio relacionado. Puede ser nulo si el evento llega sin correlacion.",
    )

    provider = models.CharField(max_length=20, default="sendgrid", db_index=True)
    event = models.CharField(max_length=40, db_index=True)
    recipient = models.CharField(
        max_length=254,
        blank=True,
        help_text="Direccion o numero al que se refiere el evento.",
    )

    provider_message_id = models.CharField(max_length=255, blank=True, db_index=True)
    provider_event_id = models.CharField(
        max_length=128,
        unique=True,
        help_text="Identificador unico del evento. Garantiza idempotencia.",
    )

    occurred_at = models.DateTimeField(db_index=True)
    reason = models.TextField(blank=True)
    status_code = models.CharField(max_length=32, blank=True)

    payload = models.JSONField(
        default=dict, help_text="Evento completo tal y como lo envio el proveedor."
    )

    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = "notification_event"
        verbose_name = "Evento de entrega"
        verbose_name_plural = "Eventos de entrega"
        ordering = ("-occurred_at",)
        indexes = [
            models.Index(fields=["message", "-occurred_at"]),
            models.Index(fields=["event", "-occurred_at"]),
        ]

    def __str__(self) -> str:
        return f"{self.event} {self.recipient} @ {self.occurred_at:%Y-%m-%d %H:%M}"
