from rest_framework import viewsets, status, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from django_filters.rest_framework import DjangoFilterBackend
from django.db.models import Q
from .models import BlogPost, BlogCategory, BlogAuthor, BlogTag, BlogComment
from .serializers import (
    BlogPostListSerializer, 
    BlogPostDetailSerializer,
    BlogCategorySerializer,
    BlogAuthorSerializer,
    BlogTagSerializer,
    BlogCommentSerializer,
    BlogCommentCreateSerializer
)


class BlogPagination(PageNumberPagination):
    """Custom pagination for blog posts"""
    page_size = 9
    page_size_query_param = 'page_size'
    max_page_size = 100


class BlogPostViewSet(viewsets.ReadOnlyModelViewSet):
    """
    ViewSet for blog posts
    Supports filtering by category, tags, author, and search
    """
    queryset = BlogPost.objects.filter(published=True)
    pagination_class = BlogPagination
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['category__slug', 'author', 'featured', 'tags__slug']
    search_fields = ['title', 'content', 'excerpt']
    ordering_fields = ['published_at', 'views_count', 'created_at']
    ordering = ['-published_at']
    lookup_field = 'slug'

    def get_serializer_class(self):
        if self.action == 'retrieve':
            return BlogPostDetailSerializer
        return BlogPostListSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        
        # Filter by category
        category_slug = self.request.query_params.get('category', None)
        if category_slug and category_slug != 'all':
            queryset = queryset.filter(category__slug=category_slug)
        
        # Filter by tag
        tag_slug = self.request.query_params.get('tag', None)
        if tag_slug:
            queryset = queryset.filter(tags__slug=tag_slug)
        
        # Filter by author
        author_id = self.request.query_params.get('author', None)
        if author_id:
            queryset = queryset.filter(author_id=author_id)
        
        # Search query
        search = self.request.query_params.get('search', None)
        if search:
            queryset = queryset.filter(
                Q(title__icontains=search) |
                Q(content__icontains=search) |
                Q(excerpt__icontains=search)
            )
        
        return queryset.distinct()

    def retrieve(self, request, *args, **kwargs):
        """Override retrieve to increment view count"""
        instance = self.get_object()
        instance.increment_views()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

    @action(detail=False, methods=['get'])
    def featured(self, request):
        """Get featured blog posts"""
        featured_posts = self.get_queryset().filter(featured=True)[:6]
        serializer = self.get_serializer(featured_posts, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=['get'])
    def latest(self, request):
        """Get latest blog posts"""
        limit = int(request.query_params.get('limit', 5))
        latest_posts = self.get_queryset()[:limit]
        serializer = self.get_serializer(latest_posts, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=['get'])
    def popular(self, request):
        """Get popular blog posts by views"""
        limit = int(request.query_params.get('limit', 5))
        popular_posts = self.get_queryset().order_by('-views_count')[:limit]
        serializer = self.get_serializer(popular_posts, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=['get'])
    def related(self, request, slug=None):
        """Get related posts for a specific post"""
        post = self.get_object()
        related_posts = self.get_queryset().filter(
            category=post.category
        ).exclude(id=post.id)[:4]
        serializer = self.get_serializer(related_posts, many=True)
        return Response(serializer.data)


class BlogCategoryViewSet(viewsets.ReadOnlyModelViewSet):
    """ViewSet for blog categories"""
    queryset = BlogCategory.objects.filter(is_active=True)
    serializer_class = BlogCategorySerializer
    lookup_field = 'slug'

    @action(detail=False, methods=['get'])
    def with_posts(self, request):
        """Get categories that have published posts"""
        categories = self.get_queryset().filter(posts__published=True).distinct()
        serializer = self.get_serializer(categories, many=True)
        return Response(serializer.data)


class BlogAuthorViewSet(viewsets.ReadOnlyModelViewSet):
    """ViewSet for blog authors"""
    queryset = BlogAuthor.objects.filter(is_active=True)
    serializer_class = BlogAuthorSerializer

    @action(detail=True, methods=['get'])
    def posts(self, request, pk=None):
        """Get all posts by a specific author"""
        author = self.get_object()
        posts = BlogPost.objects.filter(author=author, published=True)
        page = self.paginate_queryset(posts)
        if page is not None:
            serializer = BlogPostListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = BlogPostListSerializer(posts, many=True)
        return Response(serializer.data)


class BlogTagViewSet(viewsets.ReadOnlyModelViewSet):
    """ViewSet for blog tags"""
    queryset = BlogTag.objects.filter(is_active=True)
    serializer_class = BlogTagSerializer
    lookup_field = 'slug'

    @action(detail=True, methods=['get'])
    def posts(self, request, slug=None):
        """Get all posts with a specific tag"""
        tag = self.get_object()
        posts = BlogPost.objects.filter(tags=tag, published=True)
        page = self.paginate_queryset(posts)
        if page is not None:
            serializer = BlogPostListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = BlogPostListSerializer(posts, many=True)
        return Response(serializer.data)


class BlogCommentViewSet(viewsets.ModelViewSet):
    """ViewSet for blog comments"""
    queryset = BlogComment.objects.filter(is_approved=True)
    serializer_class = BlogCommentSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['post']

    def get_serializer_class(self):
        if self.action == 'create':
            return BlogCommentCreateSerializer
        return BlogCommentSerializer

    def create(self, request, *args, **kwargs):
        """Create a new comment (requires moderation)"""
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return Response(
            {
                'message': 'Comment submitted successfully. It will be visible after moderation.',
                'data': serializer.data
            },
            status=status.HTTP_201_CREATED
        )
