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 rest_framework.exceptions import ValidationError
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 api.property_api.property.models.property import PropertyReviews
from api.property_api.property.serializers.review_serializer import PropertyReviewsSerializer
from common.pagination.custom_pagination import CustomPageNumberPagination
from package_details.utils import ensure_user_has_storage_capacity
import logging

# Configure logger for property reviews
logger = logging.getLogger('property_reviews')


class PropertyReviewsPublicListAPIView(APIView):
    """Public endpoint - anybody can view all non-flagged reviews"""
    permission_classes = [AllowAny]
    
    def get(self, request):
        reviews = PropertyReviews.objects.filter(
            is_active=True, 
            is_flagged_review=False  
        ).select_related(
            'property', 
            'created_by', 
            'property__created_by',
        )
        
        # Apply filters
        property_id = request.query_params.get('property')
        rating = request.query_params.get('rating')
        
        if property_id:
            reviews = reviews.filter(property_id=property_id)
        if rating:
            reviews = reviews.filter(review_star=rating)
        
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(reviews, request)
        serializer = PropertyReviewsSerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)


class PropertyReviewsPublicListAPIView(APIView):
    """Public endpoint - anybody can view all non-flagged reviews"""
    permission_classes = [AllowAny]
    
    def get(self, request):
        reviews = PropertyReviews.objects.filter(
            is_active=True, 
            is_flagged_review=False  
        ).select_related(
            'property', 
            'created_by', 
            'property__created_by',
        )
        
        # Apply filters
        property_id = request.query_params.get('property')  # Filter by property ID
        rating = request.query_params.get('rating')  # Filter by rating
        created_by_id = request.query_params.get('created_by')  # Filter by review creator ID
        property_owner_id = request.query_params.get('property_owner')  # Filter by property owner ID
        
        if property_id:
            reviews = reviews.filter(property_id=property_id)
        if rating:
            reviews = reviews.filter(review_star=rating)
        if created_by_id:
            reviews = reviews.filter(created_by_id=created_by_id)  # Reviews created by specific user
        if property_owner_id:
            reviews = reviews.filter(property__created_by_id=property_owner_id)  # Reviews for properties owned by specific user
        
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(reviews, request)
        serializer = PropertyReviewsSerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)


class PropertyReviewsListCreateAPIView(APIView):
    """
    Authenticated endpoint for creating and listing reviews with role-based filtering:
    - Admin: Can see all reviews
    - Review Creator: Can see reviews they created
    - Property Owner: Can see reviews for their properties
    """
    permission_classes = [IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser, JSONParser]
    
    @swagger_auto_schema(request_body=PropertyReviewsSerializer)
    def post(self, request):
        # Get request tracking info
        request_id = getattr(request, 'request_id', 'unknown')
        user_id = request.user.id if request.user.is_authenticated else 'anonymous'
        
        logger.info(f"Property review creation started - User: {user_id}, Request ID: {request_id}")
        
        try:
            # ✅ Enhanced storage capacity check for both image and video
            review_image = request.FILES.get("review_image")
            review_video = request.FILES.get("review_video")
            
            # Log file detection
            if review_image:
                file_size_mb = round(review_image.size / (1024 * 1024), 2)
                logger.info(f"Image file detected - Size: {file_size_mb}MB, Type: {review_image.content_type}, User: {user_id}, Request ID: {request_id}")
            
            if review_video:
                file_size_mb = round(review_video.size / (1024 * 1024), 2)
                logger.info(f"Video file detected - Size: {file_size_mb}MB, Type: {review_video.content_type}, User: {user_id}, Request ID: {request_id}")
            
            # Storage capacity validation
            if review_image:
                logger.info(f"Starting storage capacity check for image - User: {user_id}, Request ID: {request_id}")
                ensure_user_has_storage_capacity(
                    request.user, 
                    review_image, 
                    field_name="review_image"
                )
                logger.info(f"Storage capacity check passed for image - User: {user_id}, Request ID: {request_id}")
            elif review_video:
                logger.info(f"Starting storage capacity check for video - User: {user_id}, Request ID: {request_id}")
                ensure_user_has_storage_capacity(
                    request.user, 
                    review_video, 
                    field_name="review_video"
                )
                logger.info(f"Storage capacity check passed for video - User: {user_id}, Request ID: {request_id}")

            # Serializer validation and processing
            logger.info(f"Starting serializer validation - User: {user_id}, Request ID: {request_id}")
            serializer = PropertyReviewsSerializer(data=request.data, context={'request': request})
            serializer.is_valid(raise_exception=True)
            
            logger.info(f"Serializer validation passed, saving review - User: {user_id}, Request ID: {request_id}")
            # Ensure normal reviews are created with is_flagged_review=False
            review_instance = serializer.save(is_flagged_review=False)
            
            logger.info(f"Property review created successfully - Review ID: {review_instance.id}, User: {user_id}, Request ID: {request_id}")
            return Response({"success": "Property review created successfully"}, status=status.HTTP_201_CREATED)
            
        except ValidationError as e:
            # ✅ Proper JSON error response for validation errors
            logger.warning(f"Validation error occurred - Error: {str(e)}, User: {user_id}, Request ID: {request_id}")
            return Response(e.detail, status=status.HTTP_400_BAD_REQUEST)
            
        except Exception as e:
            # ✅ Catch-all for unexpected errors with proper JSON response
            import logging
            from django.conf import settings
            logger.error(f"Unexpected error in property review creation - Error: {str(e)}, User: {user_id}, Request ID: {request_id}", exc_info=True)
            
            return Response({
                "error": "An unexpected error occurred while creating the review.",
                "detail": str(e) if settings.DEBUG else "Internal server error",
                "type": e.__class__.__name__
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def get(self, request):
        reviews = PropertyReviews.objects.filter(
            is_active=True, 
            is_flagged_review=False  
        ).select_related(
            'property', 
            'created_by', 
            'property__created_by',
        )
        
        user = request.user
        if user.role == 'admin':
            # Admin can see all reviews
            pass
        else:
            # Regular users can see:
            # 1. Reviews they created themselves
            # 2. Reviews for properties they created
            reviews = reviews.filter(
                Q(created_by=user) |  # Reviews user created
                Q(property__created_by=user)  # Reviews for user's properties
            )
        
        # Apply filters
        property_id = request.query_params.get('property')  # Filter by property ID
        rating = request.query_params.get('rating')  # Filter by rating
        created_by_id = request.query_params.get('created_by')  # Filter by review creator ID
        property_owner_id = request.query_params.get('property_owner')  # Filter by property owner ID
        
        if property_id:
            reviews = reviews.filter(property_id=property_id)
        if rating:
            reviews = reviews.filter(review_star=rating)
        if created_by_id:
            reviews = reviews.filter(created_by_id=created_by_id)  # Reviews created by specific user
        if property_owner_id:
            reviews = reviews.filter(property__created_by_id=property_owner_id)  # Reviews for properties owned by specific user
        
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(reviews, request)
        serializer = PropertyReviewsSerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)
    
    
class PropertyReviewsDetailAPIView(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 = PropertyReviews.objects.select_related(
                'property', 
                'created_by', 
                'property__created_by',
                'property__created_by__company'
            ).get(pk=pk, is_active=True, is_flagged_review=False)
            return review
        except PropertyReviews.DoesNotExist:
            return None
    
    def get_object_with_permission(self, pk, user):
        """Get review object with permission check (for PUT/DELETE)"""
        try:
            review = PropertyReviews.objects.select_related(
                'property', 
                'created_by', 
                'property__created_by',
                'property__created_by__company'
            ).get(pk=pk)
        except PropertyReviews.DoesNotExist:
            return None
        
        # Check permissions for modification
        if user.role == 'admin':
            return review
        
        # User can modify if they created the review
        if review.created_by == user:
            return review
        
        # Property owner can view but not modify
        if review.property.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": "Property review not found"}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        serializer = PropertyReviewsSerializer(review, context={'request': request})
        return Response(serializer.data)
    
    @swagger_auto_schema(request_body=PropertyReviewsSerializer)
    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": "Property review not found or you don't have permission to access it"}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        if review.created_by != request.user and request.user.role != 'admin':
            return Response(
                {"error": "You can only update reviews you created"}, 
                status=status.HTTP_403_FORBIDDEN
            )
        
        serializer = PropertyReviewsSerializer(review, data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({"success": "Property 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": "Property review not found or you don't have permission to access it"}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        if review.created_by != request.user and request.user.role != 'admin':
            return Response(
                {"error": "You can only delete reviews you created"}, 
                status=status.HTTP_403_FORBIDDEN
            )
        
        review.soft_delete()
        return Response({"success": "Property review deleted successfully"}, status=status.HTTP_200_OK)
