from django.db import transaction
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver
from slackchat.serializers import MessageSerializer

from .celery import (
    create_private_channel,
    post_webhook,
    update_users,
    verify_webhook,
)
from .models import (
    Attachment,
    Channel,
    KeywordArgument,
    Message,
    Reaction,
    User,
    Webhook,
)


@receiver(post_save, sender=Channel)
def save_channel(sender, instance, created, **kwargs):
    if created:
        create_private_channel.delay(instance.pk)


@receiver(post_save, sender=Attachment)
@receiver(post_save, sender=Message)
@receiver(post_save, sender=Reaction)
@receiver(post_save, sender=KeywordArgument)
def notify_webhook(sender, instance, created, **kwargs):
    if sender == Message:
        channel_id = instance.channel.id.hex
        message = MessageSerializer(instance=instance).data
        chat_type = instance.channel.chat_type.name

        if created:
            update_type = "message_created"
        else:
            update_type = "message_changed"
    else:
        channel_id = instance.message.channel.id.hex
        message = MessageSerializer(instance=instance.message).data
        chat_type = instance.message.channel.chat_type.name
        update_type = "message_changed"

    transaction.on_commit(
        lambda: post_webhook.delay(channel_id, chat_type, update_type, message)
    )


@receiver(post_delete, sender=Attachment)
@receiver(post_delete, sender=Reaction)
@receiver(post_delete, sender=KeywordArgument)
def notify_webhook_deletion(sender, instance, **kwargs):
    channel_id = instance.message.channel.id.hex
    message = MessageSerializer(instance=instance.message).data
    chat_type = instance.message.channel.chat_type.name
    update_type = "message_changed"

    transaction.on_commit(
        lambda: post_webhook.delay(channel_id, chat_type, update_type, message)
    )


@receiver(post_delete, sender=Message)
def notify_webhook_message_delete(sender, instance, **kwargs):
    channel_id = instance.channel.id.hex
    message = MessageSerializer(instance=instance).data
    chat_type = instance.channel.chat_type.name
    update_type = "message_deleted"

    transaction.on_commit(
        lambda: post_webhook.delay(channel_id, chat_type, update_type, message)
    )


@receiver(post_save, sender=Webhook)
def save_webhook(sender, instance, **kwargs):
    verify_webhook.delay(instance.pk)


@receiver(post_save, sender=User)
def new_user(sender, instance, created, **kwargs):
    if created:
        update_users.delay([instance.pk])
