from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated

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 drf_yasg import openapi
from django.db.models import Q
from package_details.utils import get_user_total_space_used
from service.models.services import Services
from service.serializers.services_serializer import ServiceSerializer
from common.pagination.custom_pagination import CustomPageNumberPagination
from common.exceptions.exceptions import custom_exception_handler

from rest_framework.parsers import MultiPartParser, FormParser

# from service_ownership.permissions import IsOwnerOrReadOnly
from rest_framework.permissions import AllowAny

from user_ads_package.utils import check_and_notify_low_space_users
from user_ads_package.models import UserPackage 

class ServiceSearchAPIView(APIView):
   
    permission_classes = [AllowAny]
    
    @swagger_auto_schema(
        operation_description="Search services by name, country, and state",
        manual_parameters=[
            openapi.Parameter('name', openapi.IN_QUERY, description="Search by service name", type=openapi.TYPE_STRING),
            openapi.Parameter('country', openapi.IN_QUERY, description="Filter by country", type=openapi.TYPE_STRING),
            openapi.Parameter('state', openapi.IN_QUERY, description="Filter by state", type=openapi.TYPE_STRING),
            openapi.Parameter('page', openapi.IN_QUERY, description="Page number", type=openapi.TYPE_INTEGER),
            openapi.Parameter('count', openapi.IN_QUERY, description="Items per page", type=openapi.TYPE_INTEGER),
        ]
    )
    def get(self, request):
        try:
            services = Services.objects.filter(is_active=True)\
                .select_related(
                    'service_ownership',
                    'company',
                    'category_services',
                    'created_by',
                    'city',
                    'city__state',
                    'city__state__country'
                )\
                .order_by('-created_at')
            
            name = self.request.query_params.get('name')
            country = self.request.query_params.get('country')
            state = self.request.query_params.get('state')
            
            if name:
                services = services.filter(
                    Q(name__icontains=name) |
                    Q(company__name__icontains=name) |
                    Q(category_services__name__icontains=name)
                )
            
            if country:
                services = services.filter(
                    Q(country__icontains=country) |
                    Q(city__state__country__name__icontains=country)
                )
            
            if state:
                services = services.filter(
                    Q(state__icontains=state) |
                    Q(city__state__name__icontains=state) |
                    Q(city__name__icontains=state)
                )
            
            # Paginate results
            paginator = CustomPageNumberPagination()
            result_page = paginator.paginate_queryset(services, request)
            serializer = ServiceSerializer(result_page, many=True, context={'request': request})
            
            return paginator.get_paginated_response(serializer.data)
            
        except Exception as e:
            return custom_exception_handler(e, context={})

class ServicePublicListAPIView(APIView):
    """Public endpoint to list all services for website users"""
    
    def get(self, request):
        service_type = request.query_params.get('service_category')
        category_type = request.query_params.get('category_services')
        sub_category = request.query_params.get('sub_category')
        name = self.request.query_params.get('name')
        country = self.request.query_params.get('country')
        state = self.request.query_params.get('state')
        
        service = Services.objects.filter(is_active=True)\
        .select_related(
            'service_ownership',
            'company',
            'category_services',
            'created_by',
            'city',
            'city__state',
            'city__state__country'
        )\
        .order_by('-created_at')

        if name:
            service = service.filter(
                Q(name__icontains=name) |
                Q(company__name__icontains=name) |
                Q(category_services__name__icontains=name)
            )
        if country:
            service = service.filter(
                Q(country__icontains=country) |
                Q(city__state__country__name__icontains=country)
            )
        if state:
            service = service.filter(
                Q(state__icontains=state) |
                Q(city__state__name__icontains=state) |
                Q(city__name__icontains=state)
            )
        
        if service_type:
            service = service.filter(service_category__iexact=service_type)
        if category_type:
            service = service.filter(category_services__id=category_type)
        if sub_category:
            service = service.filter(sub_category__id=sub_category)
        
        # Pagination
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(service, request)
        serializer = ServiceSerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)



class ServiceListCreateAPIView(APIView):
    parser_classes = [MultiPartParser, FormParser]
    permission_classes = [IsAuthenticated] 

    @swagger_auto_schema(request_body=ServiceSerializer)
    # def post(self, request):
    #     serializer = ServiceSerializer(data=request.data, context={'request': request})
    #     serializer.is_valid(raise_exception=True)
    #     serializer.save(created_by=request.user)
    #     return Response({"success": "Service created successfully"}, status=status.HTTP_201_CREATED)
    
    def post(self, request):
        user = request.user

        # ✅ 1. Allow admin/superuser without restriction
        if user.is_superuser or user.is_staff or user.role=="sub_admin":
            serializer = ServiceSerializer(data=request.data, context={'request': request})
            serializer.is_valid(raise_exception=True)
            serializer.save(created_by=user)
            return Response({"success": "Service created successfully"}, status=status.HTTP_201_CREATED)

        # ✅ 2. Check if user has an active 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 services."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        package = user_package.package
        # ✅ 3. Check if user has enough storage 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,
            )

        # ✅ 4. Save service if within space limit
        serializer = ServiceSerializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save(created_by=user)

        # ✅ 5. Notify if low on space
        check_and_notify_low_space_users(user)

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

    def get(self, request):
        service_type = request.query_params.get('service_category')
        category_type = request.query_params.get('category_services')
        country = self.request.query_params.get('country')
        sub_category = request.query_params.get('sub_category')
        
        service = Services.objects.filter(is_active=True)\
        .select_related('service_ownership','company','category_services', 'created_by')\
        .order_by('-created_at')  # Add created_by for user filtering
        
        user = request.user
        if user.role == 'admin':
            pass
        else:
            service = service.filter(created_by=user)
        if country:
                service = service.filter(country__icontains=country)
        if service_type:
            service = service.filter(service_category__iexact=service_type)
        if category_type:
            service = service.filter(category_services__id=category_type)
        if sub_category:
            service = service.filter(sub_category__id=sub_category)
        
        # Pagination
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(service, request)
        serializer = ServiceSerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)
    

class ServiceDetailAPIView(APIView):
    parser_classes = [MultiPartParser, FormParser]
    # permission_classes = [IsOwnerOrReadOnly]
    # def get_permissions(self):
    #     if self.request.method == "PUT":
    #         return [IsOwnerOrReadOnly()]  # Only enforce for PUT
    #     return [AllowAny()]

    @swagger_auto_schema(request_body=ServiceSerializer)
    def put(self, request, pk):
        service = get_object_or_404(Services, pk=pk)
        self.check_object_permissions(request, service)
        serializer = ServiceSerializer(service, data=request.data, partial=True, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({"success": "Service updated successfully"}, status=status.HTTP_200_OK)

    @swagger_auto_schema(request_body=ServiceSerializer)
    def patch(self, request, pk):
        service = get_object_or_404(Services, pk=pk)
        self.check_object_permissions(request, service)
        serializer = ServiceSerializer(
            service,
            data=request.data,
            partial=True,
            context={'request': request}
        )
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({"success": "Service updated successfully"}, status=status.HTTP_200_OK)

    def get(self, request, pk):
        service = get_object_or_404(Services.objects.select_related('service_ownership','company','category_services'), pk=pk)
        # self.check_object_permissions(request, service)
        serializer = ServiceSerializer(service, context={'request': request})
        return Response(serializer.data)

    def delete(self, request, pk):
        service = get_object_or_404(Services, pk=pk)
        # self.check_object_permissions(request, service)
        service.delete()
        return Response({"success": "Service deleted successfully"}, status=status.HTTP_200_OK)
    
