from django.contrib.auth.models import User
from django.db import models
from django.db.models import Case, Q, Value, When
from django.utils.timezone import now


class LeaveOfAbsenceQuerySet(models.QuerySet):
    def filter_pending(self):
        """Filter all pending requests."""
        return self.filter(Q(end=None) | Q(end__gt=now()), Q(approver=None))

    def filter_processed(self):
        """Filter all processed requests."""
        return self.filter(approver__isnull=False)

    def annotate_status(self):
        Status = self.model.Status
        return self.annotate(
            status=Case(
                When(approver__isnull=True, then=Value(Status.PENDING)),
                When(reason__isnull=False, then=Value(Status.DENIED)),
                default=Value(Status.APPROVED),
            )
        )


class LeaveOfAbsenceManagerBase(models.Manager):
    def unapproved_count(self):
        """Count number of unapproved requests."""
        return self.filter_pending().count()


LeaveOfAbsenceManager = LeaveOfAbsenceManagerBase.from_queryset(LeaveOfAbsenceQuerySet)


class InactivityPingConfigQueryset(models.QuerySet):
    def relevant_for_user(self, user: User):
        """Webhooks that are relevant for the given user."""
        pks = {config.pk for config in self.all() if config.is_applicable_to(user)}
        return self.filter(pk__in=pks)


class InactivityPingConfigManagerBase(models.Manager):
    pass


InactivityPingConfigManager = InactivityPingConfigManagerBase.from_queryset(
    InactivityPingConfigQueryset
)


class WebhookQueryset(models.QuerySet):
    def relevant_for_user(self, user: User):
        """Webhooks that are relevant for the given user."""
        from .models import InactivityPingConfig

        configs = list(InactivityPingConfig.objects.relevant_for_user(user))
        return self.filter(Q(ping_configs__in=configs) | Q(ping_configs=None))


class WebhookManagerBase(models.Manager):
    def send_message_to_active_webhooks(self, loa, notif_type, message):
        webhooks = self.relevant_for_user(loa.user).filter(
            is_active=True, notification_types__contains=notif_type
        )
        for webhook in webhooks:
            webhook.send_message(message)


WebhookManager = WebhookManagerBase.from_queryset(WebhookQueryset)
