from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated, AllowAny
from drf_yasg.utils import swagger_auto_schema
from django.shortcuts import get_object_or_404
from django.db.models import Q
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser

from producers_products.models.producers_products import ProductsReview
from producers_products.serializers.product_review_serializer import ProductsReviewSerializer
from common.pagination.custom_pagination import CustomPageNumberPagination
from package_details.utils import ensure_user_has_storage_capacity


class ProductsReviewPublicListAPIView(APIView):
    """Public endpoint - anybody can view all non-flagged product reviews"""
    permission_classes = [AllowAny]
    
    def get(self, request):
        reviews = ProductsReview.objects.filter(
            is_active=True, 
            is_flagged_review=False  
        ).select_related(
            'product', 
            'created_by',
            'product__created_by'
        )
        
        # Apply filters
        product_id = request.query_params.get('product')  
        rating = request.query_params.get('rating')  
        created_by_id = request.query_params.get('created_by') 
        product_owner_id = request.query_params.get('product_owner')  
        
        if product_id:
            reviews = reviews.filter(product_id=product_id)
        if rating:
            reviews = reviews.filter(review_star=rating)
        if created_by_id:
            reviews = reviews.filter(created_by_id=created_by_id)
        if product_owner_id:
            reviews = reviews.filter(product__created_by_id=product_owner_id)
        
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(reviews, request)
        serializer = ProductsReviewSerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)


class ProductsReviewListCreateAPIView(APIView):
    """
    Authenticated endpoint for creating and listing reviews with role-based filtering:
    - Admin: Can see all reviews
    - Review Creator: Can see reviews they created
    - Product Owner: Can see reviews for their products
    """
    permission_classes = [IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser, JSONParser]
    
    @swagger_auto_schema(request_body=ProductsReviewSerializer)
    def post(self, request):
        # ✅ Enhanced storage capacity check for both image and video
        review_image = request.FILES.get("review_image")
        review_video = request.FILES.get("review_video")
        
        if review_image:
            ensure_user_has_storage_capacity(
                request.user, 
                review_image, 
                field_name="review_image"
            )
        elif review_video:
            ensure_user_has_storage_capacity(
                request.user, 
                review_video, 
                field_name="review_video"
            )

        serializer = ProductsReviewSerializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save(is_flagged_review=False)
        return Response({"success": "Product review created successfully"}, status=status.HTTP_201_CREATED)
    
    def get(self, request):
        reviews = ProductsReview.objects.filter(
            is_active=True, 
            is_flagged_review=False
        ).select_related(
            'product', 
            'created_by',
            'product__created_by'
        )
        
        user = request.user
        if user.role == 'admin':
            # Admin can see all reviews
            pass
        else:
            
            reviews = reviews.filter(
                Q(created_by=user) |  
                Q(product__created_by=user) 
            )
        
        # Apply filters
        product_id = request.query_params.get('product')  
        rating = request.query_params.get('rating')  
        created_by_id = request.query_params.get('created_by')  
        product_owner_id = request.query_params.get('product_owner')  
        
        if product_id:
            reviews = reviews.filter(product_id=product_id)
        if rating:
            reviews = reviews.filter(review_star=rating)
        if created_by_id:
            reviews = reviews.filter(created_by_id=created_by_id)
        if product_owner_id:
            reviews = reviews.filter(product__created_by_id=product_owner_id)
        
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(reviews, request)
        serializer = ProductsReviewSerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)


class ProductsReviewDetailAPIView(APIView):
    """
    Detail view accessible to:
    - Anyone (public access for GET)
    - Review creator (for PUT/DELETE)
    - Admin (for all operations)
    """
    parser_classes = [MultiPartParser, FormParser, JSONParser]
    
    def get_permissions(self):
        """Allow public GET access, but require authentication for other methods"""
        if self.request.method == 'GET':
            return [AllowAny()]
        return [IsAuthenticated()]
    
    def get_object(self, pk):
        """Get review object without permission check (for public GET)"""
        try:
            review = ProductsReview.objects.select_related(
                'product', 
                'created_by',
                'product__created_by'
            ).get(pk=pk, is_active=True, is_flagged_review=False)
            return review
        except ProductsReview.DoesNotExist:
            return None
    
    def get_object_with_permission(self, pk, user):
        """Get review object with permission check (for PUT/DELETE)"""
        try:
            review = ProductsReview.objects.select_related(
                'product', 
                'created_by',
                'product__created_by'
            ).get(pk=pk)
        except ProductsReview.DoesNotExist:
            return None
        
        if user.role == 'admin':
            return review
        
        if review.created_by == user:
            return review
        
        if review.product.created_by == user:
            return review
        
        return None
    
    def get(self, request, pk):
        """Public GET - anybody can view a specific review"""
        review = self.get_object(pk)
        if not review:
            return Response(
                {"error": "Product review not found"}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        serializer = ProductsReviewSerializer(review, context={'request': request})
        return Response(serializer.data)
    
    @swagger_auto_schema(request_body=ProductsReviewSerializer)
    def put(self, request, pk):
        """Only review creator or admin can update"""
        review = self.get_object_with_permission(pk, request.user)
        if not review:
            return Response(
                {"error": "Product review not found or you don't have permission to access it"}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        # Only the review creator can update their own review
        if review.created_by != request.user and request.user.role != 'admin':
            return Response(
                {"error": "You do not have permission to update this review"}, 
                status=status.HTTP_403_FORBIDDEN
            )
        
        serializer = ProductsReviewSerializer(review, data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({"success": "Product review updated successfully"}, status=status.HTTP_200_OK)

    def delete(self, request, pk):
        """Only review creator or admin can delete"""
        review = self.get_object_with_permission(pk, request.user)
        if not review:
            return Response(
                {"error": "Product review not found or you don't have permission to access it"}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        # Only the review creator can delete their own review
        if review.created_by != request.user and request.user.role != 'admin':
            return Response(
                {"error": "You do not have permission to delete this review"}, 
                status=status.HTTP_403_FORBIDDEN
            )
        
        review.soft_delete()
        return Response({"success": "Product review deleted successfully"}, status=status.HTTP_200_OK)
