from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.pagination import PageNumberPagination
from rest_framework.exceptions import ValidationError, NotFound
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.permissions import IsAuthenticated
from common.permission import HasActivePackage
from user_ads_package.models import UserPackage 

from api.property_api.property.models.property import Property
from api.property_api.property.serializers.property_serializer import PropertySerializer, PropertyDropdownSerializer
from common.pagination.custom_pagination import CustomPageNumberPagination

from package_details.utils import get_user_total_space_used
from user_ads_package.utils import check_and_notify_low_space_users

class PropertyBuyListAPIView(APIView):
    def get(self, request):
        properties = Property.objects.filter(is_active=True, listed_for=1).select_related('country','city','state').prefetch_related('property','media') #todo: add property_facilities later
        # count = request.query_params.get('count')
        # if count and count.isdigit():
        #     properties = properties[:int(count)]
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(properties, request)
        serializer = PropertySerializer(result_page, many=True, context={'request': request})
        # return Response(serializer.data, status=status.HTTP_200_OK)
        return paginator.get_paginated_response(serializer.data)
    

class PropertyBuyDetailAPIView(APIView):
    # @swagger_auto_schema(request_body=PropertySerializer)
    def get(self, request, pk):
        property = get_object_or_404(Property.objects.select_related('country','city','state').prefetch_related('property','media'), pk=pk) #todo: add property_facilities later
        serializer = PropertySerializer(property, context={'request': request})
        return Response(serializer.data)


class PropertyRentListAPIView(APIView):
    def get(self, request):
        properties = Property.objects.filter(is_active=True, listed_for=2).prefetch_related('property','media')\
        .select_related('country','city','state') #todo: add property_facilities later
        # count = request.query_params.get('count')
        # if count and count.isdigit():
        #     properties = properties[:int(count)]
        # serializer = PropertySerializer(properties, many=True)
        # return Response(serializer.data, status=status.HTTP_200_OK)
        
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(properties, request)
        serializer = PropertySerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)
    

class PropertyRentDetailAPIView(APIView):
    # @swagger_auto_schema(request_body=PropertySerializer)
    def get(self, request, pk):
        property = get_object_or_404(Property.objects.select_related('country','city','state').prefetch_related('property','media'), pk=pk) #todo: add property_facilities later
        serializer = PropertySerializer(property, context={'request': request})
        return Response(serializer.data)


class PropertyPublicListAPIView(APIView):
    """Public endpoint to list all properties for website users"""
    
    def get(self, request):
        property_type = request.query_params.get('listed_for')
        property_agent = request.query_params.get('agent')
        
        properties = Property.objects.filter(is_active=True).prefetch_related('property','media')\
        .select_related('country','city','state', 'created_by')
        
        if property_type:
            properties = properties.filter(listed_for__iexact=property_type)
        if property_agent:
            properties = properties.filter(agent__id__iexact=property_agent)
        
        # Pagination
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(properties, request)
        serializer = PropertySerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)

class PropertyListCreateAPIView(APIView):
    permission_classes = [IsAuthenticated,HasActivePackage]  # Add authentication requirement
    
    @swagger_auto_schema(request_body=PropertySerializer)
    # def post(self, request):
    #     serializer = PropertySerializer(data=request.data, context={'request': request})
    #     serializer.is_valid(raise_exception=True)
    #     # Automatically set the created_by field to the current user
    #     serializer.save(created_by=request.user)
    #     return Response({"success": "Property created successfully"}, status=status.HTTP_201_CREATED)

    def post(self, request):
        user = request.user
        user_role = getattr(user, 'role', None)

        # Skip for admin or superuser
        if user.is_superuser or user.is_staff or user_role == "agent":
            serializer = PropertySerializer(data=request.data, context={'request': request})
            serializer.is_valid(raise_exception=True)
            serializer.save(created_by=user)
            return Response({"success": "Property created successfully"}, status=status.HTTP_201_CREATED)

        # Check if user has a package
        user_package = (
        UserPackage.objects.filter(user=user)
        .order_by('-end_date')
        .first()
        )
        if not user_package:
            return Response(
                {"error": "You do not have an active package to post properties."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        package = user_package.package
        # Check available space
        used = get_user_total_space_used(user)
        limit = float(package.space)

        if used >= limit:
            return Response(
                {
                    "error": f"You've reached your storage limit ({used:.2f} MB of {limit:.2f} MB). "
                             "Please upgrade your package."
                },
                status=status.HTTP_400_BAD_REQUEST,
            )

        # Create property (user has space)
        serializer = PropertySerializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save(created_by=user)

        # After creation, check & notify for low space
        check_and_notify_low_space_users(user)

        return Response(
            {"success": "Property created successfully"},
            status=status.HTTP_201_CREATED
        )


    def get(self, request):
        property_type = request.query_params.get('listed_for')
        property_agent = request.query_params.get('agent')
        country_id = request.query_params.get('country')

        properties = (
            Property.objects
            .filter(is_active=True)
            .select_related('country', 'city', 'state', 'created_by')
            .prefetch_related('property', 'media')
        )

        user = request.user

        # ROLE-BASED ACCESS
        if user.role == 'agent':
            properties = properties.filter(
                Q(created_by=user) |
                Q(agent__agent_user=user)
            )
        elif user.role != 'admin':
            # normal users
            properties = properties.filter(created_by=user)

        if property_type:
            properties = properties.filter(listed_for=property_type)

        if property_agent:
            properties = properties.filter(agent__id=property_agent)

        if country_id:
            properties = properties.filter(country__id=country_id)

        # 📄 Pagination
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(properties, request)
        serializer = PropertySerializer(
            result_page,
            many=True,
            context={'request': request}
        )

        return paginator.get_paginated_response(serializer.data) 

class PropertyDetailAPIView(APIView):
    @swagger_auto_schema(request_body=PropertySerializer)
    def put(self, request, pk):
        property = get_object_or_404(Property, pk=pk)
        serializer = PropertySerializer(property, data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({"success": "Property updated successfully"}, status=status.HTTP_200_OK)

    def get(self, request, pk):
        property = get_object_or_404(Property.objects.select_related('country','city','state').prefetch_related('property','media'), pk=pk) #todo: add property_facilities later
        serializer = PropertySerializer(property, context={'request': request})
        return Response(serializer.data)

    def delete(self, request, pk):
        property = get_object_or_404(Property, pk=pk)
        property.soft_delete()
        return Response({"success": "Property deleted successfully"}, status=status.HTTP_200_OK)
    
    
class PropertyExistAPIView(APIView):
    def get(self, request, name):
        if not isinstance(name, str) or not name.strip():
            raise ValidationError("Property name is required.")

        trimmed_name = name.strip()
        exists = Property.objects.filter(name__iexact=trimmed_name).exists()
        return Response({"isExist": exists}, status=status.HTTP_200_OK)
    

class PropertyDropdownAPIView(APIView):
    def get(self, request):
        properties = Property.objects.filter(is_active=True)
        serializer = PropertyDropdownSerializer(properties, many=True, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)