from django.db.models import Count, Q
from django_filters import rest_framework as filters

from verify_trusted.companies.models import Company


class CompanyFilter(filters.FilterSet):
    name = filters.CharFilter(method='name_filter')
    domain = filters.CharFilter(field_name='url')
    platform = filters.CharFilter(method='platform_filter')
    first_letter = filters.CharFilter(method='first_letter_filter')
    has_reviews = filters.BooleanFilter(method='has_reviews_filter')
    has_email_company = filters.BooleanFilter(method='has_email_filter')
    rating_star = filters.NumberFilter(method='rating_star_filter')

    class Meta:
        model = Company
        fields = ['user', 'category', 'category_main', 'is_verified']

    def name_filter(self, queryset, name, value):
        queryset = queryset.filter(search_vector=value)
        return queryset

    def platform_filter(self, queryset, name, value):
        queryset = queryset.filter(review_sources__platform_id__in=value.split(','))
        return queryset

    def first_letter_filter(self, queryset, name, value):
        first_letter: str = value[:1]
        first_letter_query = Q(first_letter=first_letter.lower()) | Q(
            first_letter=first_letter.upper()
        )  # Do not uses istartswith
        queryset = Company.objects.only(
            'id',
            'name',
            'url',
            'url_display',
        ).filter(first_letter_query)
        return queryset

    def has_reviews_filter(self, queryset, name, value):
        if value is True:
            queryset = queryset.filter(reviews_count__gt=0)
        else:
            queryset = queryset.filter(Q(reviews_count=0) | Q(reviews_count__isnull=True))
        return queryset

    def has_email_filter(self, queryset, name, value):
        if value is True:
            queryset = queryset.filter(email__isnull=False)
        else:
            queryset = queryset.filter(email__isnull=True)
        return queryset

    def rating_star_filter(self, queryset, name, value):
        if value == 0:
            queryset = queryset.filter(average_rating__lt=3)
        else:
            queryset = queryset.filter(average_rating__gte=3)
        return queryset
