from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType
from django.db.models.query import QuerySet
from django.utils import timezone

from .models import Notification


def notify_handler(verb, **kwargs):
    """
    Handler function to create Notification instance upon action signal call.
    """
    # Pull the options out of kwargs
    kwargs.pop("signal", None)
    recipient = kwargs.pop("recipient")
    actor = kwargs.pop("sender")
    optional_objs = [(kwargs.pop(opt, None), opt) for opt in ("target", "action_object")]
    public = bool(kwargs.pop("public", True))
    description = kwargs.pop("description", None)
    timestamp = kwargs.pop("timestamp", timezone.now())
    level = kwargs.pop("level", Notification.LEVELS.info)

    # Check if User or Group
    if isinstance(recipient, Group):
        recipients = recipient.user_set.all()
    elif isinstance(recipient, (QuerySet, list)):
        recipients = recipient
    else:
        recipients = [recipient]

    new_notifications = []

    for recipient in recipients:
        newnotify = Notification(
            recipient=recipient,
            actor_content_type=ContentType.objects.get_for_model(actor),
            actor_object_id=actor.pk,
            verb=str(verb),
            public=public,
            description=description,
            timestamp=timestamp,
            level=level,
        )

        # Set optional objects
        for obj, opt in optional_objs:
            if obj is not None:
                setattr(newnotify, "%s_object_id" % opt, obj.pk)
                setattr(newnotify, "%s_content_type" % opt, ContentType.objects.get_for_model(obj))

        newnotify.data = kwargs
        newnotify.save()

        new_notifications.append(newnotify)

    return new_notifications
