"""Views for app favorites."""
from rest_framework import generics

from establishment.filters import EstablishmentFilter
from establishment.models import Establishment
from establishment.serializers import EstablishmentSimilarSerializer
from news.filters import NewsListFilterSet
from news.models import News
from news.serializers import NewsListSerializer
from product.filters import ProductFilterSet
from product.models import Product
from product.serializers import ProductBaseSerializer
from utils.methods import get_permission_classes
from utils.permissions import (
    IsApprovedUser, IsEstablishmentAdministrator, IsWineryWineInspector,
    IsRestaurantInspector, IsContentPageManager, IsEstablishmentManager,
    IsReviewManager, IsDistilleryLiquorInspector, IsArtisanInspector,
    IsGuest, IsModerator, IsProducerFoodInspector,
)


class FavoritesPermissionMixin:
    """Permissions for application favorites."""
    permission_classes = get_permission_classes(
        IsApprovedUser, IsEstablishmentAdministrator, IsWineryWineInspector,
        IsRestaurantInspector, IsContentPageManager, IsEstablishmentManager,
        IsReviewManager, IsDistilleryLiquorInspector, IsArtisanInspector,
        IsModerator, IsProducerFoodInspector,
    )


class FavoritesEstablishmentListView(FavoritesPermissionMixin, generics.ListAPIView):
    """List views for establishments in favorites."""

    serializer_class = EstablishmentSimilarSerializer
    filter_class = EstablishmentFilter
    permission_classes = get_permission_classes(
        IsApprovedUser, IsEstablishmentAdministrator, IsWineryWineInspector,
        IsRestaurantInspector, IsContentPageManager, IsEstablishmentManager,
        IsReviewManager, IsDistilleryLiquorInspector, IsArtisanInspector,
        IsGuest, IsModerator, IsProducerFoodInspector,
    )

    def get_queryset(self):
        """Override get_queryset method"""
        return Establishment.objects.filter(favorites__user=self.request.user) \
            .order_by('-favorites').with_base_related() \
            .with_certain_tag_category_related('category', 'restaurant_category') \
            .with_certain_tag_category_related('cuisine', 'restaurant_cuisine') \
            .with_certain_tag_category_related('shop_category', 'artisan_category') \
            .with_certain_tag_category_related('distillery_type', 'distillery_type')


class FavoritesProductListView(FavoritesPermissionMixin, generics.ListAPIView):
    """List views for products in favorites."""

    serializer_class = ProductBaseSerializer
    filter_class = ProductFilterSet

    def get_queryset(self):
        """Override get_queryset method"""
        return Product.objects.filter(favorites__user=self.request.user) \
            .order_by('-favorites')


class FavoritesNewsListView(FavoritesPermissionMixin, generics.ListAPIView):
    """List views for news in favorites."""

    serializer_class = NewsListSerializer
    filter_class = NewsListFilterSet

    def get_queryset(self):
        """Override get_queryset method"""
        return News.objects.filter(favorites__user=self.request.user).order_by('-favorites')
