from django.shortcuts import get_object_or_404
from django.utils import timezone
from rest_framework.generics import ListAPIView, RetrieveAPIView
from django_filters.rest_framework import DjangoFilterBackend
from django.utils.encoding import uri_to_iri
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework import filters
from . import models as blogModel
from core import paginations
from . import serializers
from . import functions


class CarArticlesList(ListAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.CarArticlesListSerializer
    pagination_class = paginations.Set15ForPagination
    filter_backends = [filters.SearchFilter, DjangoFilterBackend]
    filterset_fields = ['car', 'car__english_name', 'brand', 'brand__english_name', 'type']
    search_fields = ['title', 'content']

    def get_queryset(self):
        offset = self.request.query_params.get('offset')
        limit = self.request.query_params.get('limit')
        if offset is not None and limit is not None:
            limit = int(offset) + int(limit)
            return blogModel.CarArticle.objects.filter(published__lte=timezone.now())[int(offset):limit]
        return blogModel.CarArticle.objects.filter(published__lte=timezone.now())


class CarArticlesIdsList(ListAPIView):
    permission_classes = [permissions.AllowAny]
    queryset = blogModel.CarArticle.objects.all()
    serializer_class = serializers.CarArticlesIdsListSerializer


class CarArticleDetails(RetrieveAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.CarArticleDetailSerializer

    def get_queryset(self):
        queryset = blogModel.CarArticle.objects.all()
        article = queryset.filter(id=self.kwargs.get('pk')).first()
        ip_address = functions.get_ip(self.request.META.get('HTTP_X_FORWARDED_FOR'), self.request.META.get('REMOTE_ADDR'))
        if ip_address not in article.view.all():
            article.view.add(ip_address)
        return queryset


class CarArticleDetailsByLink(RetrieveAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.CarArticleDetailSerializer

    def get(self, request, *args, **kwargs):
        article = get_object_or_404(blogModel.CarArticle, link=uri_to_iri(self.kwargs.get('link')))
        serializer = self.get_serializer(article)
        ip_address = functions.get_ip(self.request.META.get('HTTP_X_FORWARDED_FOR'),
                                      self.request.META.get('REMOTE_ADDR'))
        if ip_address not in article.view.all():
            article.view.add(ip_address)
        return Response(serializer.data)


class ProductArticlesList(ListAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.ProductArticlesListSerializer
    pagination_class = paginations.Set15ForPagination
    filter_backends = [filters.SearchFilter, DjangoFilterBackend]
    filterset_fields = ['subcategory__category', 'subcategory', 'product']
    search_fields = ['title', 'content']

    def get_queryset(self):
        offset = self.request.query_params.get('offset')
        limit = self.request.query_params.get('limit')
        if offset is not None and limit is not None:
            limit = int(offset) + int(limit)
            return blogModel.ProductArticle.objects.filter(published__lte=timezone.now()).order_by('-id')[int(offset):limit]
        return blogModel.ProductArticle.objects.filter(published__lte=timezone.now()).order_by('-id')


class ProductArticlesIdsList(ListAPIView):
    permission_classes = [permissions.AllowAny]
    queryset = blogModel.ProductArticle.objects.all()
    serializer_class = serializers.ProductArticlesIdsListSerializer


class ProductArticleDetails(RetrieveAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.ProductArticleDetailSerializer

    def get_queryset(self):
        queryset = blogModel.ProductArticle.objects.all()
        article = queryset.filter(id=self.kwargs.get('pk')).first()
        ip_address = functions.get_ip(self.request.META.get('HTTP_X_FORWARDED_FOR'), self.request.META.get('REMOTE_ADDR'))
        if ip_address not in article.view.all():
            article.view.add(ip_address)
        return queryset


class ProductArticleDetailsByLink(RetrieveAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.ProductArticleDetailSerializer

    def get(self, request, *args, **kwargs):
        article = get_object_or_404(blogModel.ProductArticle, link=uri_to_iri(self.kwargs.get('link')))
        serializer = self.get_serializer(article)
        ip_address = functions.get_ip(self.request.META.get('HTTP_X_FORWARDED_FOR'),
                                      self.request.META.get('REMOTE_ADDR'))
        if ip_address not in article.view.all():
            article.view.add(ip_address)
        return Response(serializer.data)


class OtherArticlesList(ListAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.OtherArticlesListSerializer
    pagination_class = paginations.Set15ForPagination
    filter_backends = [filters.SearchFilter]
    search_fields = ['title', 'content']

    def get_queryset(self):
        offset = self.request.query_params.get('offset')
        limit = self.request.query_params.get('limit')
        if offset is not None and limit is not None:
            limit = int(offset) + int(limit)
            return blogModel.Other.objects.filter(published__lte=timezone.now()).order_by('-id')[int(offset):limit]
        return blogModel.Other.objects.filter(published__lte=timezone.now()).order_by('-id')


class OtherArticlesIdsList(ListAPIView):
    permission_classes = [permissions.AllowAny]
    queryset = blogModel.Other.objects.all()
    serializer_class = serializers.OtherArticlesIdsListSerializer


class OtherArticleDetails(RetrieveAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.OtherArticleDetailSerializer

    def get_queryset(self):
        queryset = blogModel.Other.objects.all()
        article = queryset.filter(id=self.kwargs.get('pk')).first()
        ip_address = functions.get_ip(self.request.META.get('HTTP_X_FORWARDED_FOR'), self.request.META.get('REMOTE_ADDR'))
        if ip_address not in article.view.all():
            article.view.add(ip_address)
        return queryset


class OtherArticleDetailsByLink(RetrieveAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.OtherArticleDetailSerializer

    def get(self, request, *args, **kwargs):
        article = get_object_or_404(blogModel.Other, link=uri_to_iri(self.kwargs.get('link')))
        serializer = self.get_serializer(article)
        ip_address = functions.get_ip(self.request.META.get('HTTP_X_FORWARDED_FOR'),
                                      self.request.META.get('REMOTE_ADDR'))
        if ip_address not in article.view.all():
            article.view.add(ip_address)
        return Response(serializer.data)


class NewsList(ListAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.NewsListSerializer
    pagination_class = paginations.Set15ForPagination
    filter_backends = [filters.SearchFilter]
    search_fields = ['title', 'content']

    def get_queryset(self):
        offset = self.request.query_params.get('offset')
        limit = self.request.query_params.get('limit')
        if offset is not None and limit is not None:
            limit = int(offset) + int(limit)
            return blogModel.News.objects.filter(published__lte=timezone.now()).order_by('-id')[int(offset):limit]
        return blogModel.News.objects.filter(published__lte=timezone.now()).order_by('-id')


class NewsIdsList(ListAPIView):
    permission_classes = [permissions.AllowAny]
    queryset = blogModel.News.objects.all()
    serializer_class = serializers.NewsIdsListSerializer


class NewsDetails(RetrieveAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.NewsDetailSerializer

    def get_queryset(self):
        queryset = blogModel.News.objects.all()
        article = queryset.filter(id=self.kwargs.get('pk')).first()
        ip_address = functions.get_ip(self.request.META.get('HTTP_X_FORWARDED_FOR'), self.request.META.get('REMOTE_ADDR'))
        if ip_address not in article.view.all():
            article.view.add(ip_address)
        return queryset


class NewsDetailsByLink(RetrieveAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.NewsDetailSerializer

    def get(self, request, *args, **kwargs):
        article = get_object_or_404(blogModel.News, link=uri_to_iri(self.kwargs.get('link')))
        serializer = self.get_serializer(article)
        ip_address = functions.get_ip(self.request.META.get('HTTP_X_FORWARDED_FOR'),
                                      self.request.META.get('REMOTE_ADDR'))
        if ip_address not in article.view.all():
            article.view.add(ip_address)
        return Response(serializer.data)

# api versioning is implemented  self.request.version
