from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from django.shortcuts import get_object_or_404
from django.db import transaction

from api.property_api.property.models.property import Property, PropertyReviews
from api.property_api.property.serializers.property_serializer import PropertySerializer
from api.property_api.property.serializers.review_serializer import PropertyReviewsSerializer
from common.pagination.custom_pagination import CustomPageNumberPagination
from notification.models import Notification

class PropertyFlagAPIView(APIView):
    permission_classes = [IsAuthenticated]
    
    # Swagger schema for flagging a property
    @swagger_auto_schema(
        operation_description="Flag property and create a flagged review",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={
                'message': openapi.Schema(
                    type=openapi.TYPE_STRING,
                    description='Reason for flagging the property',
                    example='This property violates community guidelines'
                )
            },
            required=['message']
        )
    )
    def post(self, request, pk):
        property_obj = get_object_or_404(Property, pk=pk)
        # if request.user.role != 'admin' and property_obj.created_by != request.user:
        #     return Response(
        #         {"error": "You don't have permission to flag this property"}, 
        #         status=status.HTTP_403_FORBIDDEN
        #     )
        
        # Validate that message is provided
        message = request.data.get('message', '').strip()
        if not message:
            return Response(
                {"error": "Message is required when flagging a property"}, 
                status=status.HTTP_400_BAD_REQUEST
            )
        
        
        
        # Use transaction to ensure both property flagging and review creation happen together
        with transaction.atomic():
            # Flag the property
            property_obj.is_flagged = True
            property_obj.save(update_fields=['is_flagged'])
            
            # Create a new review with user's message
            flagged_review = PropertyReviews.objects.create(
                property=property_obj,
                review_star=1,
                message=message,
                is_flagged_review=True,
                created_by=request.user
            )

            Notification.objects.create(
                notification_type='property_report',
                property_report_id=property_obj.id,
                title=f'Property Flagged: {property_obj.name if hasattr(property_obj, "name") else "Property"} (ID: {property_obj.id})',
                message=message,
                status='unread'
            )
        
        return Response({
            "success": "Property flagged and review created successfully",
            "property_id": property_obj.id,
            "is_flagged": property_obj.is_flagged,
            "review_id": flagged_review.id,
            "message": flagged_review.message
        }, status=status.HTTP_200_OK)
    

class PropertyUnflagAPIView(APIView):
    permission_classes = [IsAuthenticated]
    
    @swagger_auto_schema(
        operation_description="Set property flag to False by ID",
        responses={
            200: openapi.Response(
                description="Property unflagged successfully",
            )
        }
    )
    def post(self, request, pk):
        """Set is_flagged to False for a specific property"""
        property_obj = get_object_or_404(Property, pk=pk)
        
        if request.user.role != 'admin' and property_obj.created_by != request.user:
            return Response(
                {"error": "You don't have permission to unflag this property"}, 
                status=status.HTTP_403_FORBIDDEN
            )
        
        property_obj.is_flagged = False
        property_obj.save(update_fields=['is_flagged'])
        
        return Response({
            "success": "Property unflagged successfully",
            "property_id": property_obj.id,
            "is_flagged": property_obj.is_flagged
        }, status=status.HTTP_200_OK)









class PropertyFlaggedListAPIView(APIView):
    permission_classes = [IsAuthenticated]
    
    @swagger_auto_schema(
        operation_description="Get paginated list of flagged properties with only flagged reviews",
        manual_parameters=[
            openapi.Parameter('page', openapi.IN_QUERY, description="Page number", type=openapi.TYPE_INTEGER),
            openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER),
            openapi.Parameter('listed_for', openapi.IN_QUERY, description="Filter by property listing type", type=openapi.TYPE_STRING),
            openapi.Parameter('agent', openapi.IN_QUERY, description="Filter by agent ID", type=openapi.TYPE_INTEGER),
            openapi.Parameter('country', openapi.IN_QUERY, description="Filter by country ID", type=openapi.TYPE_INTEGER),
            openapi.Parameter('city', openapi.IN_QUERY, description="Filter by city ID", type=openapi.TYPE_INTEGER),
            openapi.Parameter('state', openapi.IN_QUERY, description="Filter by state ID", type=openapi.TYPE_INTEGER),
            openapi.Parameter('include_reviews', openapi.IN_QUERY, description="Include flagged reviews in response", type=openapi.TYPE_BOOLEAN),
        ]
    )
    def get(self, request):
        properties = Property.objects.filter(is_flagged=True, is_active=True).select_related(
            'country', 'city', 'state', 'agent', 'created_by'
        ).prefetch_related('property', 'media').order_by('-created_at')
        
        user = request.user
        if user.role != 'admin':
            properties = properties.filter(created_by=user)
        
        # Apply filters
        listed_for = request.query_params.get('listed_for')
        agent_id = request.query_params.get('agent')
        country_id = request.query_params.get('country')
        city_id = request.query_params.get('city')
        state_id = request.query_params.get('state')
        include_reviews = request.query_params.get('include_reviews', 'false').lower() == 'true'
        
        if listed_for:
            properties = properties.filter(listed_for__iexact=listed_for)
        if agent_id:
            properties = properties.filter(agent_id=agent_id)
        if country_id:
            properties = properties.filter(country_id=country_id)
        if city_id:
            properties = properties.filter(city_id=city_id)
        if state_id:
            properties = properties.filter(state_id=state_id)
        
        # Pagination
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(properties, request)
        serializer = PropertySerializer(result_page, many=True, context={'request': request})
        
        response_data = paginator.get_paginated_response(serializer.data)
        
        # If requested, include ONLY flagged reviews for each property
        if include_reviews:
            for property_data in response_data.data['results']:
                property_id = property_data['id']
                # Only get reviews that are flagged (is_flagged_review=True)
                flagged_reviews = PropertyReviews.objects.filter(
                    property_id=property_id,
                    is_flagged_review=True,  # Only flagged reviews
                    is_active=True
                ).select_related('created_by')
                
                reviews_serializer = PropertyReviewsSerializer(flagged_reviews, many=True, context={'request': request})
                property_data['flagged_reviews'] = reviews_serializer.data
                property_data['flagged_reviews_count'] = flagged_reviews.count()
        
        return response_data