"""Search indexes app views."""
from django_elasticsearch_dsl_drf import constants
from django_elasticsearch_dsl_drf.filter_backends import (
    FilteringFilterBackend,
    GeoSpatialOrderingFilterBackend,
    OrderingFilterBackend,
)
from django_elasticsearch_dsl_drf.viewsets import BaseDocumentViewSet
from elasticsearch_dsl import TermsFacet
from rest_framework import permissions

from product.models import Product
from search_indexes import serializers, filters, utils
from search_indexes.documents import EstablishmentDocument, NewsDocument
from search_indexes.documents.product import ProductDocument
from utils.pagination import ESDocumentPagination


class NewsDocumentViewSet(BaseDocumentViewSet):
    """News document ViewSet."""

    def get_queryset(self):
        qs = super(NewsDocumentViewSet, self).get_queryset()
        qs = qs.filter('match', has_any_desc_active=True)
        return qs

    document = NewsDocument
    lookup_field = 'slug'
    pagination_class = ESDocumentPagination
    permission_classes = (permissions.AllowAny,)
    serializer_class = serializers.NewsDocumentSerializer

    filter_backends = [
        filters.CustomSearchFilterBackend,
        FilteringFilterBackend,
        filters.CustomFacetedSearchFilterBackend,
        OrderingFilterBackend
    ]

    ordering_fields = {
        'start': {
            'field': 'start',
        },
    }

    faceted_search_fields = {
        'tag': {
            'field': 'tags.id',
            'enabled': True,
            'facet': TermsFacet,
            'options': {
                'size': utils.FACET_MAX_RESPONSE,
            },
        },
    }

    search_fields = {
        'title': {'fuzziness': 'auto:2,5',
                  'boost': 3},
        'subtitle': {'fuzziness': 'auto:2,5',
                     'boost': 2},
        'description': {'fuzziness': 'auto:2,5'},
    }
    translated_search_fields = (
        'title',
        'subtitle',
        'description',
    )

    filter_fields = {
        'tags_id': {
            'field': 'tags.id',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE,
            ],
        },
        'tag': {
            'field': 'tags.id',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE,
            ]
        },
        'tag_value': {
            'field': 'tags.value',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE
            ]
        },
        'slug': 'slug',
        'country_id': {
            'field': 'country.id'
        },
        'country': {
            'field': 'country.code'
        },
    }


class MobileNewsDocumentViewSet(NewsDocumentViewSet):

    filter_backends = [
        filters.CustomSearchFilterBackend,
        FilteringFilterBackend,
    ]


class EstablishmentDocumentViewSet(BaseDocumentViewSet):
    """Establishment document ViewSet."""

    document = EstablishmentDocument
    pagination_class = ESDocumentPagination
    permission_classes = (permissions.AllowAny,)
    serializer_class = serializers.EstablishmentDocumentSerializer

    def get_queryset(self):
        qs = super(EstablishmentDocumentViewSet, self).get_queryset()
        qs = qs.filter('match', is_publish=True)
        return qs

    filter_backends = [
        FilteringFilterBackend,
        filters.CustomSearchFilterBackend,
        filters.CustomGeoSpatialFilteringFilterBackend,
        filters.CustomFacetedSearchFilterBackend,
        GeoSpatialOrderingFilterBackend,
    ]

    faceted_search_fields = {
        'works_at_weekday': {
            'field': 'works_at_weekday',
            'facet': TermsFacet,
            'enabled': True,
        },
        'toque_number': {
            'field': 'toque_number',
            'enabled': True,
            'facet': TermsFacet,
        },
        'works_noon': {
            'field': 'works_noon',
            'facet': TermsFacet,
            'enabled': True,
        },
        'works_evening': {
            'field': 'works_evening',
            'facet': TermsFacet,
            'enabled': True,
        },
        'works_now': {
            'field': 'works_now',
            'facet': TermsFacet,
            'enabled': True,
        },
        'tag': {
            'field': 'tags.id',
            'facet': TermsFacet,
            'enabled': True,
            'options': {
                'size': utils.FACET_MAX_RESPONSE,
            },
        },
        'wine_colors': {
            'field': 'products.wine_colors.id',
            'facet': TermsFacet,
            'enabled': True,
            'options': {
                'size': utils.FACET_MAX_RESPONSE,
            },
        },
        'wine_region_id': {
            'field': 'wine_origins.wine_region.id',
            'facet': TermsFacet,
            'enabled': True,
            'options': {
                'size': utils.FACET_MAX_RESPONSE,
            },
        },
        'wine_sub_region_id': {
            'field': 'wine_origins.wine_sub_region.id',
            'facet': TermsFacet,
            'enabled': True,
            'options': {
                'size': utils.FACET_MAX_RESPONSE,
            },
        }
    }

    search_fields = {
        'name': {'fuzziness': 'auto:2,5',
                 'boost': 4},
        'transliterated_name': {'fuzziness': 'auto:2,5',
                                'boost': 3},
        'description': {'fuzziness': 'auto:2,5'},
    }
    translated_search_fields = (
        'description',
    )
    filter_fields = {
        'slug': 'slug',
        'tag': {
            'field': 'tags.id',
            'lookups': [constants.LOOKUP_QUERY_IN]
        },
        'toque_number': {
            'field': 'toque_number',
            'lookups': [
                constants.LOOKUP_FILTER_RANGE,
                constants.LOOKUP_QUERY_GT,
                constants.LOOKUP_QUERY_GTE,
                constants.LOOKUP_QUERY_LT,
                constants.LOOKUP_QUERY_LTE,
                constants.LOOKUP_QUERY_IN,
            ]
        },
        'price_level': {
            'field': 'price_level',
            'lookups': [
                constants.LOOKUP_FILTER_RANGE,
                constants.LOOKUP_QUERY_GT,
                constants.LOOKUP_QUERY_GTE,
                constants.LOOKUP_QUERY_LT,
                constants.LOOKUP_QUERY_LTE,
                constants.LOOKUP_QUERY_IN,
            ]
        },
        'wine_colors_id': {
            'field': 'products.wine_colors.id',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE,
            ],
        },
        'wine_region_id': {
            'field': 'wine_origins.wine_region.id',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE,
            ],
        },
        'wine_sub_region_id': {
            'field': 'wine_origins.wine_sub_region.id',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE,
            ],
        },
        'country_id': {
            'field': 'address.city.country.id'
        },
        'country': {
            'field': 'address.city.country.code'
        },
        'tags_id': {
            'field': 'tags.id',
        },
        'tags_category_id': {
            'field': 'tags.category.id',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
            ],
        },
        'collection_type': {
            'field': 'collections.collection_type'
        },
        'establishment_type': {
            'field': 'establishment_type.id'
        },
        'establishment_subtypes': {
            'field': 'establishment_subtypes.id'
        },
        'type': {
            'field': 'establishment_type.index_name'
        },
        'subtype': {
            'field': 'establishment_subtypes.index_name',
        },
        'works_noon': {
            'field': 'works_noon',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
            ],
        },
        'works_at_weekday': {
            'field': 'works_at_weekday',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
            ],
        },
        'works_evening': {
            'field': 'works_evening',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
            ],
        },
        'works_now': {
            'field': 'works_now',
            'lookups': [
                constants.LOOKUP_FILTER_TERM,
            ]
        },
    }

    geo_spatial_filter_fields = {
        'location': {
            'field': 'address.coordinates',
            'lookups': [
                constants.LOOKUP_FILTER_GEO_BOUNDING_BOX,
            ]
        }
    }

    geo_spatial_ordering_fields = {
        'location': {
            'field': 'address.coordinates',
        },
    }


class MobileEstablishmentDocumentViewSet(EstablishmentDocumentViewSet):

    filter_backends = [
        FilteringFilterBackend,
        filters.CustomSearchFilterBackend,
        filters.CustomGeoSpatialFilteringFilterBackend,
        GeoSpatialOrderingFilterBackend,
    ]


class ProductDocumentViewSet(BaseDocumentViewSet):
    """Product document ViewSet."""

    document = ProductDocument
    pagination_class = ESDocumentPagination
    permission_classes = (permissions.AllowAny,)
    serializer_class = serializers.ProductDocumentSerializer

    filter_backends = [
        FilteringFilterBackend,
        filters.CustomSearchFilterBackend,
        filters.CustomFacetedSearchFilterBackend,
        OrderingFilterBackend,
        # GeoSpatialOrderingFilterBackend,
    ]


    def get_queryset(self):
        qs = super(ProductDocumentViewSet, self).get_queryset()
        qs = qs.filter('match', state=Product.PUBLISHED)
        return qs

    ordering_fields = {
        'created': {
            'field': 'created',
        },
    }

    search_fields = {
        'name': {'fuzziness': 'auto:2,5',
                 'boost': 8},
        'name_ru': {'fuzziness': 'auto:2,5',
                 'boost': 6},
        'name_fr': {'fuzziness': 'auto:2,5',
                 'boost': 7},
        'transliterated_name': {'fuzziness': 'auto:2,5',
                                'boost': 3},
        'description': {'fuzziness': 'auto:2,5'},
    }

    faceted_search_fields = {
        'tag': {
            'field': 'tags.id',
            'enabled': True,
            'facet': TermsFacet,
            'options': {
                'size': utils.FACET_MAX_RESPONSE,
            },
        },
        'wine_region_id': {
            'field': 'wine_origins.wine_region.id',
            'facet': TermsFacet,
            'enabled': True,
            'options': {
                'size': utils.FACET_MAX_RESPONSE,
            },
        },
        'wine_sub_region_id': {
            'field': 'wine_origins.wine_sub_region.id',
            'facet': TermsFacet,
            'enabled': True,
            'options': {
                'size': utils.FACET_MAX_RESPONSE,
            },
        }
    }

    translated_search_fields = (
        'description',
    )

    filter_fields = {
        'slug': 'slug',
        'tags_id': {
            'field': 'tags.id',
            'lookups': [constants.LOOKUP_QUERY_IN],
        },
        'country': {
            'field': 'establishment.city.country.code',
        },
        'wine_colors_id': {
            'field': 'wine_colors.id',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE,
            ],
        },
        'wine_region_id': {
            'field': 'wine_origins.wine_region.id',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE,
            ],
        },
        'wine_sub_region_id': {
            'field': 'wine_origins.wine_sub_region.id',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE,
            ],
        },
        'grape_variety_id': {
            'field': 'grape_variety.id',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE,
            ]
        },
        # 'wine_from_country_code': {
        #     'field': 'wine_origins.wine_region.country.code',
        # },
        'for_establishment': {
            'field': 'establishment.slug',
        },
        'product_type': {
            'field': 'product_type.index_name',
        },
        'subtype': {
            'field': 'subtypes.index_name',
            'lookups': [
                constants.LOOKUP_QUERY_IN,
                constants.LOOKUP_QUERY_EXCLUDE,
            ],
        },
    }


class MobileProductDocumentViewSet(ProductDocumentViewSet):

    filter_backends = [
        FilteringFilterBackend,
        filters.CustomSearchFilterBackend,
    ]
