import django_filters
from django.db.models import Count, Sum

from ...account.models import User
from ..core.filters import EnumFilter, ObjectTypeFilter
from ..core.types.common import DateRangeInput, IntRangeInput, PriceRangeInput
from ..utils.filters import filter_by_query_param, filter_range_field
from .enums import StaffMemberStatus


def filter_date_joined(qs, _, value):
    return filter_range_field(qs, "date_joined__date", value)


def filter_money_spent(qs, _, value):
    qs = qs.annotate(money_spent=Sum("orders__total_gross_amount"))
    return filter_range_field(qs, "money_spent", value)


def filter_number_of_orders(qs, _, value):
    qs = qs.annotate(total_orders=Count("orders"))
    return filter_range_field(qs, "total_orders", value)


def filter_placed_orders(qs, _, value):
    return filter_range_field(qs, "orders__created__date", value)


def filter_status(qs, _, value):
    if value == StaffMemberStatus.ACTIVE:
        qs = qs.filter(is_staff=True, is_active=True)
    elif value == StaffMemberStatus.DEACTIVATED:
        qs = qs.filter(is_staff=True, is_active=False)
    return qs


def filter_staff_search(qs, _, value):
    search_fields = (
        "email",
        "first_name",
        "last_name",
        "default_shipping_address__first_name",
        "default_shipping_address__last_name",
        "default_shipping_address__city",
        "default_shipping_address__country",
        "default_shipping_address__phone",
    )
    if value:
        qs = filter_by_query_param(qs, value, search_fields)
    return qs


def filter_search(qs, _, value):
    search_fields = ("name",)
    if value:
        qs = filter_by_query_param(qs, value, search_fields)
    return qs


class CustomerFilter(django_filters.FilterSet):
    date_joined = ObjectTypeFilter(
        input_class=DateRangeInput, method=filter_date_joined
    )
    money_spent = ObjectTypeFilter(
        input_class=PriceRangeInput, method=filter_money_spent
    )
    number_of_orders = ObjectTypeFilter(
        input_class=IntRangeInput, method=filter_number_of_orders
    )
    placed_orders = ObjectTypeFilter(
        input_class=DateRangeInput, method=filter_placed_orders
    )
    search = django_filters.CharFilter(method=filter_staff_search)

    class Meta:
        model = User
        fields = [
            "date_joined",
            "money_spent",
            "number_of_orders",
            "placed_orders",
            "search",
        ]


class PermissionGroupFilter(django_filters.FilterSet):
    search = django_filters.CharFilter(method=filter_search)


class StaffUserFilter(django_filters.FilterSet):
    status = EnumFilter(input_class=StaffMemberStatus, method=filter_status)
    search = django_filters.CharFilter(method=filter_staff_search)

    # TODO - Figure out after permision types
    # department = ObjectTypeFilter

    class Meta:
        model = User
        fields = ["status", "search"]
