from django.contrib.auth.models import User
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
import django_filters as filters

from . import models


__all__ = (
    "PageFilters",
    "EpisodeFilters",
    "ImageFilterSet",
    "SoundFilterSet",
    "TrackFilterSet",
    "UserFilterSet",
    "GroupFilterSet",
    "UserGroupFilterSet",
)


class PageFilters(filters.FilterSet):
    q = filters.CharFilter(method="search_filter", label=_("Search"))

    class Meta:
        model = models.Page
        fields = {
            "category__id": ["in", "exact"],
            "pub_date": ["exact", "gte", "lte"],
        }

    def search_filter(self, queryset, name, value):
        return queryset.search(value)


class EpisodeFilters(PageFilters):
    podcast = filters.BooleanFilter(method="podcast_filter", label=_("Podcast"))

    class Meta:
        model = models.Episode
        fields = PageFilters.Meta.fields.copy()

    def podcast_filter(self, queryset, name, value):
        if value:
            return queryset.filter(sound__is_public=True).distinct()
        return queryset.filter(sound__isnull=True)


class ImageFilterSet(filters.FilterSet):
    search = filters.CharFilter(field_name="search", method="search_filter")

    def search_filter(self, queryset, name, value):
        return queryset.filter(original_filename__icontains=value)


class SoundFilterSet(filters.FilterSet):
    station = filters.NumberFilter(field_name="program__station__id")
    program = filters.NumberFilter(field_name="program_id")
    # episode = filters.NumberFilter(field_name="episode_id")
    search = filters.CharFilter(field_name="search", method="search_filter")

    class Meta:
        model = models.Sound
        fields = {
            #    "episode": ["in", "exact", "isnull"],
        }

    def search_filter(self, queryset, name, value):
        return queryset.search(value)


class TrackFilterSet(filters.FilterSet):
    artist = filters.CharFilter(field_name="artist", lookup_expr="icontains")
    album = filters.CharFilter(field_name="album", lookup_expr="icontains")
    title = filters.CharFilter(field_name="title", lookup_expr="icontains")


class UserFilterSet(filters.FilterSet):
    search = filters.CharFilter(field_name="search", method="search_filter")
    in_group = filters.NumberFilter(field_name="in_group", method="in_group_filter")
    not_in_group = filters.NumberFilter(field_name="not_in_group", method="not_in_group_filter")

    def in_group_filter(self, queryset, name, value):
        return queryset.filter(groups__in=[value])

    def not_in_group_filter(self, queryset, name, value):
        return queryset.exclude(groups__in=[value])

    def search_filter(self, queryset, name, value):
        return queryset.filter(
            Q(username__icontains=value) | Q(first_name__icontains=value) | Q(last_name__icontains=value)
        )


class GroupFilterSet(filters.FilterSet):
    search = filters.CharFilter(field_name="search", method="search_filter")
    no_user = filters.NumberFilter(field_name="no_user", method="no_user_filter")

    def no_user_filter(self, queryset, name, value):
        return queryset.exclude(user__in=[value])

    def search_filter(self, queryset, name, value):
        return queryset.filter(Q(name__icontains=value) | Q(program__title__icontains=value))


class UserGroupFilterSet(filters.FilterSet):
    class Meta:
        model = User.groups.through
        fields = ["group", "user"]

    def filter_queryset(self, queryset):
        queryset = super().filter_queryset(queryset)
        if self.form.cleaned_data.get("user"):
            queryset = queryset.order_by("group__name")
        elif self.form.cleaned_data.get("group"):
            queryset = queryset.order_by("user__first_name")
        return queryset
