from django.db.models import BooleanField, Case, F, Manager, Q, QuerySet, Sum, Value, When
from django.db.models.functions import Coalesce
from django.utils.timezone import now


class GatewayQuerySet(QuerySet):
    def with_usage_sums(self) -> QuerySet:
        today = now().date()
        current_month_start = today.replace(day=1)
        return self.annotate(
            daily_sum=Coalesce(Sum("transactions__amount", filter=Q(transactions__created__date=today)), Value(0.0)),
            monthly_sum=Coalesce(
                Sum("transactions__amount", filter=Q(transactions__created__date__gte=current_month_start)), Value(0.0)
            ),
        )

    def can_be_used(self) -> QuerySet:
        qs = self.with_usage_sums()
        qs = qs.annotate(
            daily_ok=Case(
                When(daily_limit=0, then=Value(True)),
                When(daily_sum__lt=F("daily_limit"), then=Value(True)),
                default=Value(False),
                output_field=BooleanField(),
            ),
            monthly_ok=Case(
                When(monthly_limit=0, then=Value(True)),
                When(monthly_sum__lt=F("monthly_limit"), then=Value(True)),
                default=Value(False),
                output_field=BooleanField(),
            ),
        )
        return qs.annotate(
            can_be_used=Case(
                When(daily_ok=True, monthly_ok=True, is_active=True, then=Value(True)),
                default=Value(False),
                output_field=BooleanField(),
            )
        ).order_by("-priority")


class GatewayManager(Manager.from_queryset(GatewayQuerySet)):
    def get_queryset(self) -> QuerySet:
        return super().get_queryset().can_be_used()
