"""News app views."""
from django.conf import settings
from django.shortcuts import get_object_or_404
from django.utils import translation
from rest_framework import generics, permissions, response

from news import filters, models, serializers
from rating.tasks import add_rating
from utils.permissions import IsCountryAdmin, IsContentPageManager
from utils.views import CreateDestroyGalleryViewMixin, FavoritesCreateDestroyMixinView, CarouselCreateDestroyMixinView
from utils.serializers import ImageBaseSerializer, EmptySerializer


class NewsMixinView:
    """News mixin."""

    permission_classes = (permissions.AllowAny,)
    serializer_class = serializers.NewsBaseSerializer

    def get_queryset(self, *args, **kwargs):
        """Override get_queryset method."""
        qs = models.News.objects.published() \
            .with_base_related() \
            .annotate_in_favorites(self.request.user) \
            .order_by('-is_highlighted', '-publication_date', '-publication_time')

        country_code = self.request.country_code
        if country_code:
            if kwargs.get('international_preferred') and country_code in settings.INTERNATIONAL_COUNTRY_CODES:
                qs = qs.international_news()
            else:
                qs = qs.by_country_code(country_code)

        # locale = kwargs.get('locale')
        # if locale:
        #     qs = qs.by_locale(locale)

        return qs

    def get_object(self):
        return self.get_queryset() \
            .filter(slugs__values__contains=[self.kwargs['slug']]).first()


class NewsListView(NewsMixinView, generics.ListAPIView):
    """News list view."""

    serializer_class = serializers.NewsListSerializer
    filter_class = filters.NewsListFilterSet

    def get_queryset(self, *args, **kwargs):
        locale = translation.get_language()
        kwargs.update({
            'international_preferred': True,
            'locale': locale,
        })
        return super().get_queryset(*args, **kwargs)\
            .filter(locale_to_description_is_active__values__contains=['True'])


class NewsDetailView(NewsMixinView, generics.RetrieveAPIView):
    """News detail view."""

    lookup_field = None
    serializer_class = serializers.NewsDetailWebSerializer

    def get_queryset(self):
        """Override get_queryset method."""
        qs = models.News.objects.all().annotate_in_favorites(self.request.user)
        return qs


class NewsTypeListView(generics.ListAPIView):
    """NewsType list view."""

    pagination_class = None
    permission_classes = (permissions.AllowAny,)
    queryset = models.NewsType.objects.all()
    serializer_class = serializers.NewsTypeSerializer


class NewsBackOfficeMixinView:
    """News back office mixin view."""

    permission_classes = (permissions.IsAuthenticated,)

    def get_queryset(self):
        """Override get_queryset method."""
        qs = models.News.objects.with_base_related() \
            .annotate_in_favorites(self.request.user) \
            .order_by('-is_highlighted', '-created')
        return qs


class NewsBackOfficeLCView(NewsBackOfficeMixinView,
                           generics.ListCreateAPIView):
    """Resource for a list of news for back-office users."""

    serializer_class = serializers.NewsBackOfficeBaseSerializer
    filter_class = filters.NewsListFilterSet
    create_serializers_class = serializers.NewsBackOfficeDetailSerializer

    permission_classes = [IsCountryAdmin | IsContentPageManager]

    def get_serializer_class(self):
        """Override serializer class."""
        if self.request.method == 'POST':
            return self.create_serializers_class
        return super().get_serializer_class()

    def get_queryset(self):
        """Override get_queryset method."""
        qs = super().get_queryset().with_extended_related()
        if self.request.country_code:
            qs = qs.by_country_code(self.request.country_code)
        return qs


class NewsBackOfficeGalleryCreateDestroyView(NewsBackOfficeMixinView,
                                             CreateDestroyGalleryViewMixin):
    """Resource for a create gallery for news for back-office users."""
    serializer_class = serializers.NewsBackOfficeGallerySerializer

    def create(self, request, *args, **kwargs):
        _ = super().create(request, *args, **kwargs)
        news_qs = self.filter_queryset(self.get_queryset())
        return response.Response(
            data=serializers.NewsBackOfficeDetailSerializer(get_object_or_404(news_qs, pk=kwargs.get('pk'))).data
        )

    def get_object(self):
        """
        Returns the object the view is displaying.
        """
        news_qs = self.filter_queryset(self.get_queryset())

        news = get_object_or_404(news_qs, pk=self.kwargs.get('pk'))
        gallery = get_object_or_404(news.news_gallery, image_id=self.kwargs.get('image_id'))

        # May raise a permission denied
        self.check_object_permissions(self.request, gallery)

        return gallery


class NewsBackOfficeGalleryListView(NewsBackOfficeMixinView,
                                    generics.ListAPIView):
    """Resource for returning gallery for news for back-office users."""
    serializer_class = ImageBaseSerializer

    def get_object(self):
        """Override get_object method."""
        qs = super(NewsBackOfficeGalleryListView, self).get_queryset()
        news = get_object_or_404(qs, pk=self.kwargs.get('pk'))

        # May raise a permission denied
        self.check_object_permissions(self.request, news)

        return news

    def get_queryset(self):
        """Override get_queryset method."""
        return self.get_object().crop_gallery


class NewsBackOfficeRUDView(NewsBackOfficeMixinView,
                            generics.RetrieveUpdateDestroyAPIView):
    """Resource for detailed information about news for back-office users."""

    serializer_class = serializers.NewsBackOfficeDetailSerializer
    permission_classes = [IsCountryAdmin | IsContentPageManager]

    def get(self, request, pk, *args, **kwargs):
        add_rating(remote_addr=request.META.get('REMOTE_ADDR'),
                   pk=pk, model='news', app_label='news')
        return self.retrieve(request, *args, **kwargs)


class NewsFavoritesCreateDestroyView(FavoritesCreateDestroyMixinView):
    """View for create/destroy news from favorites."""

    _model = models.News
    serializer_class = serializers.NewsFavoritesCreateSerializer


class NewsCarouselCreateDestroyView(CarouselCreateDestroyMixinView):
    """View for create/destroy news from carousel."""

    _model = models.News
    serializer_class = serializers.NewsCarouselCreateSerializer


class NewsCloneView(generics.CreateAPIView):
    """View for creating clone News"""
    permission_classes = (permissions.AllowAny,)
    serializer_class = serializers.NewsCloneCreateSerializer
    queryset = models.News.objects.all()
