from django.utils.decorators import method_decorator
from drf_yasg.utils import swagger_auto_schema
from requests import Response
from rest_framework.mixins import RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, ListModelMixin
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.viewsets import GenericViewSet

from verify_trusted.blogs.api.filter.blog import BlogFilter
from verify_trusted.blogs.api.params import title_param, first_letter_param, status_param, category_param
from verify_trusted.blogs.api.serializers import BlogSerializer, BlogFirstLetterSerializer, BlogListSerializer, \
    BlogUpdateSerializer
from verify_trusted.blogs.models import Blog
from verify_trusted.users.api.paginations import BlogResultsSetPagination

search_params = [
    title_param,
    status_param,
    category_param,
    first_letter_param
]


class BaseBlogViewSet(GenericViewSet):
    queryset = (
        Blog.objects.order_by('-id')
            .select_related('category')
            .prefetch_related('tags')
            .defer(
            'title',
            'summary',
            'body',
            'date_create',
            'search_vector',
        )
            .all()
    )
    serializer_class = BlogSerializer


@method_decorator(
    name='list', decorator=swagger_auto_schema(manual_parameters=search_params)
)
class BaseBlogListViewSet(ListModelMixin, GenericViewSet):
    pagination_class = BlogResultsSetPagination
    permission_classes = [IsAuthenticatedOrReadOnly]
    filterset_class = BlogFilter

    def get_serializer_class(self):
        if self.action in ['list', 'retrieve']:
            if (
                self.action == 'list'
                and self.request.query_params.get(first_letter_param.name, None)
                is not None
            ):
                return BlogFirstLetterSerializer
            return BlogListSerializer
        return super().get_serializer_class()


class BlogViewSet(
    CreateModelMixin,
    UpdateModelMixin,
    BaseBlogListViewSet,
    BaseBlogViewSet,
):

    def get_serializer_class(self):
        if self.action == 'update':
            return BlogUpdateSerializer
        return super().get_serializer_class()

    def get_queryset(self):
        queryset = super().get_queryset()
        if self.action in ['update', 'partial_update']:
            # Only owner can update
            queryset = queryset.filter(user=self.request.user)
        return queryset

    def perform_update(self, serializer):
        super().perform_update(serializer)




