from enum import Enum

import celery
from django.contrib.auth import get_user_model

from django.db import models, transaction
from django.db.models.signals import post_save
from django.dispatch import receiver
from bridger.buttons import WidgetButton
from django.conf import settings

class NotificationSendType(Enum):
    SYSTEM = "system"
    MAIL = "mail"
    SYSTEM_AND_MAIL = "system_and_mail"


class Notification(models.Model):
    """
        A model that represents a notification that is send as a system notification or mail or both
    """

    recipient = models.ForeignKey(to=get_user_model(), related_name="notifications", on_delete=models.CASCADE)

    title = models.CharField(max_length=512)
    message = models.TextField(null=True, blank=True)
    buttons = models.JSONField(default=list, null=True, blank=True)

    endpoint = models.URLField(null=True, blank=True, max_length=2048)

    timestamp_created = models.DateTimeField(auto_now_add=True, verbose_name="Created")
    timestamp_received = models.DateTimeField(null=True, blank=True, verbose_name="Received")
    timestamp_read = models.DateTimeField(null=True, blank=True, verbose_name="Read")
    timestamp_mailed = models.DateTimeField(null=True, blank=True, verbose_name="Mailed")

    send_type_choices = (
        (NotificationSendType.SYSTEM.value, "System"),
        (NotificationSendType.MAIL.value, "Mail"),
        (NotificationSendType.SYSTEM_AND_MAIL.value, "System and Mail"),
    )

    send_type = models.CharField(max_length=32, choices=send_type_choices, default=NotificationSendType.SYSTEM.value,)

    def __str__(self):
        return f"{self.recipient} {self.title}"

    def to_payload(self):
        return {
            "id": self.id,
            "title": self.title,
            "message": self.message,
            "buttons": self.buttons,
            "endpoint": self.endpoint,
        }
    def get_endpoint_basename(cls):
        return "bridger:notification"

@receiver(post_save, sender=Notification)
def post_create_notification(sender, instance, created, **kwargs):
    from .tasks import send_mail, send_system
    if created:
        dispatch = {
            NotificationSendType.MAIL.value: [send_mail],
            NotificationSendType.SYSTEM.value: [send_system],
            NotificationSendType.SYSTEM_AND_MAIL.value: [send_system, send_mail],
        }
        for action in dispatch[instance.send_type]:
            try:
                action.apply_async((instance.id,), countdown=getattr(settings, "BRIDGER_NOTIFICATION_DELAY_SECONDS", 10))
            except Exception as e:
                pass
            # transaction.on_commit(lambda: celery.execute.send_task(action, args=[instance.id]))
