"""Establishment app filters."""
from django.core.validators import EMPTY_VALUES
from django.utils.translation import ugettext_lazy as _
from django_filters import rest_framework as filters
from rest_framework.serializers import ValidationError

from establishment import models


class EstablishmentFilter(filters.FilterSet):
    """Establishment filter set."""

    tag_id = filters.NumberFilter(field_name='tags__metadata__id', )
    award_id = filters.NumberFilter(field_name='awards__id', )
    search = filters.CharFilter(method='search_text')
    type = filters.CharFilter(method='by_type')
    subtype = filters.CharFilter(method='by_subtype')
    city_id = filters.CharFilter(field_name='address__city__id')
    city_name = filters.CharFilter(field_name='address__city__name')

    class Meta:
        """Meta class."""

        model = models.Establishment
        fields = (
            'tag_id',
            'award_id',
            'search',
            'type',
            'subtype',
            'city_id',
            'city_name',
        )

    def search_text(self, queryset, name, value):
        """Search text."""
        if value not in EMPTY_VALUES:
            return queryset.search(value, locale=self.request.locale)
        return queryset

    def by_type(self, queryset, name, value):
        if value not in EMPTY_VALUES:
            return queryset.by_type(value)
        return queryset

    def by_subtype(self, queryset, name, value):
        if value not in EMPTY_VALUES:
            return queryset.by_subtype(value)
        return queryset


class EstablishmentTypeTagFilter(filters.FilterSet):
    """Establishment tag filter set."""

    type_id = filters.NumberFilter(field_name='id')

    class Meta:
        """Meta class."""

        model = models.EstablishmentType
        fields = (
            'type_id',
        )


class EmployeeBackFilter(filters.FilterSet):
    """Employee filter set."""

    search = filters.CharFilter(method='search_by_name_or_last_name')
    position_id = filters.NumberFilter(method='search_by_actual_position_id')
    public_mark = filters.NumberFilter(method='search_by_public_mark')
    toque_number = filters.NumberFilter(method='search_by_toque_number')
    username = filters.CharFilter(method='search_by_username_or_name')

    class Meta:
        """Meta class."""

        model = models.Employee
        fields = (
            'search',
            'position_id',
            'public_mark',
            'toque_number',
            'username',
        )

    def search_by_name_or_last_name(self, queryset, name, value):
        """Search by name or last name."""
        if value not in EMPTY_VALUES:
            return queryset.trigram_search(value)
        return queryset

    def search_by_actual_position_id(self, queryset, name, value):
        """Search by actual position_id."""
        if value not in EMPTY_VALUES:
            return queryset.search_by_position_id(value)
        return queryset

    def search_by_public_mark(self, queryset, name, value):
        """Search by establishment public_mark."""
        if value not in EMPTY_VALUES:
            return queryset.search_by_public_mark(value)
        return queryset

    def search_by_toque_number(self, queryset, name, value):
        """Search by establishment toque_number."""
        if value not in EMPTY_VALUES:
            return queryset.search_by_toque_number(value)
        return queryset

    def search_by_username_or_name(self, queryset, name, value):
        """Search by username or name."""
        if value not in EMPTY_VALUES:
            return queryset.search_by_username_or_name(value)
        return queryset


class EmployeeBackSearchFilter(EmployeeBackFilter):
    def search_by_name_or_last_name(self, queryset, name, value):
        if value not in EMPTY_VALUES:
            if len(value) < 3:
                raise ValidationError({'detail': _('Type at least 3 characters to search please.')})
            return queryset.trigram_search(value)
        return queryset
