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

from common.permission import HasActivePackage
from package_details.utils import get_user_total_space_used
from producers_products.models.producers_products import ProducersProducts
from producers_products.serializers.producers_products_serializer import ProducersProductsSerializer
from common.pagination.custom_pagination import CustomPageNumberPagination
from common.exceptions.exceptions import custom_exception_handler

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 ProducersProductsSearchAPIView(APIView):
   
    permission_classes = [AllowAny]
    
    @swagger_auto_schema(
        operation_description="Search producers products by name, country, and state",
        manual_parameters=[
            openapi.Parameter('name', openapi.IN_QUERY, description="Search by product 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:
            products = ProducersProducts.objects.filter(is_active=True).select_related('sub_category', 'created_by')\
                .prefetch_related('product_color','product_image','product_size','product_variant')
            
            name = self.request.query_params.get('name')
            country = self.request.query_params.get('country')
            state = self.request.query_params.get('state')
            
            # Apply filters
            if name:
                products = products.filter(name__icontains=name)
            
            if country:
                products = products.filter(country__icontains=country)
            
            if state:
                products = products.filter(state__icontains=state)
            
            # Paginate results
            paginator = CustomPageNumberPagination()
            result_page = paginator.paginate_queryset(products, request)
            serializer = ProducersProductsSerializer(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 ProducersProductsPublicListAPIView(APIView):
    """Public endpoint to list all producers products for website users"""
    
    def get(self, request):
        categories = ProducersProducts.objects.filter(is_active=True).select_related('sub_category', 'created_by')\
        .prefetch_related('product_color','product_image','product_size','product_variant')
        
        category_by_name = self.request.query_params.get('brand')
        category_by_max_price = self.request.query_params.get('max_price')
        category_by_min_price = self.request.query_params.get('min_price')
        category_by_sub = self.request.query_params.get('sub-category')
        products_by_category = self.request.query_params.get('category')
        product_by_type = self.request.query_params.get('product')
        
        if products_by_category:
           categories = categories.select_related('sub_category__category').filter(
            sub_category__category__id=products_by_category,
            is_active=True
        )
        if category_by_sub:
            categories = categories.filter(sub_category__id__iexact=category_by_sub)
        if category_by_name:
            categories = categories.filter(brand__icontains=category_by_name)
        if category_by_max_price:
            categories = categories.filter(price__lte=category_by_max_price)
        if category_by_min_price:
            categories = categories.filter(price__gte=category_by_min_price)
        if product_by_type:
            categories = categories.filter(products_type__iexact=product_by_type)
            
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(categories, request)
        serializer = ProducersProductsSerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)


class ProducersProductsListCreateAPIView(APIView):
    permission_classes = [IsAuthenticated, HasActivePackage]  
    
    @swagger_auto_schema(request_body=ProducersProductsSerializer)
    # def post(self, request):
    #     serializer = ProducersProductsSerializer(data=request.data, context={'request': request})
    #     serializer.is_valid(raise_exception=True)
    #     serializer.save(created_by=request.user)
    #     return Response({"Success": "Producers products created successfully"}, status=status.HTTP_201_CREATED)
    
    def post(self, request):
        user = request.user

        # ✅ 1. Allow admin/superuser to skip checks
        if user.is_superuser or user.is_staff:
            serializer = ProducersProductsSerializer(data=request.data, context={'request': request})
            serializer.is_valid(raise_exception=True)
            serializer.save(created_by=user)
            return Response({"Success": "Producers products 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 products."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        package = user_package.package
        # ✅ 3. Calculate used vs total 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 producer product
        serializer = ProducersProductsSerializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save(created_by=user)

        # ✅ 5. Trigger low-space notification (if usage >= 80%)
        check_and_notify_low_space_users(user)

        return Response({"Success": "Producers products created successfully"}, status=status.HTTP_201_CREATED)


    def get(self, request):
        categories = ProducersProducts.objects.filter(is_active=True).select_related('sub_category', 'created_by')\
        .prefetch_related('product_color','product_image','product_size','product_variant')
        
        user = request.user
        if user.role == 'admin':
            pass
        else:
            categories = categories.filter(created_by=user)
        
        category_by_name = self.request.query_params.get('brand')
        category_by_max_price = self.request.query_params.get('max_price')
        category_by_min_price = self.request.query_params.get('min_price')
        category_by_sub = self.request.query_params.get('sub-category')
        products_by_category = self.request.query_params.get('category')
        product_by_type = self.request.query_params.get('product')
        
        if products_by_category:
           categories = categories.select_related('sub_category__category').filter(
            sub_category__category__id=products_by_category,
            is_active=True
        )
        if category_by_sub:
            categories = categories.filter(sub_category__id__iexact=category_by_sub)
        if category_by_name:
            categories = categories.filter(brand__icontains=category_by_name)
        if category_by_max_price:
            categories = categories.filter(price__lte=category_by_max_price)
        if category_by_min_price:
            categories = categories.filter(price__gte=category_by_min_price)
        if product_by_type:
            categories = categories.filter(products_type__iexact=product_by_type)
            
        paginator = CustomPageNumberPagination()
        result_page = paginator.paginate_queryset(categories, request)
        serializer = ProducersProductsSerializer(result_page, many=True, context={'request': request})
        return paginator.get_paginated_response(serializer.data)
    

class ProducersProductsDetailAPIView(APIView):
    permission_classes = [AllowAny]
    @swagger_auto_schema(request_body=ProducersProductsSerializer)
    def put(self, request, pk):
        category = get_object_or_404(ProducersProducts, pk=pk)
        serializer = ProducersProductsSerializer(category, data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({"Success": "Producers products updated successfully"}, status=status.HTTP_200_OK)
    
    def get(self, request, pk):
        category = get_object_or_404(ProducersProducts.objects.filter(is_active=True).select_related('sub_category')\
        .prefetch_related('product_color','product_image','product_size','product_variant'), pk=pk)
        serializer = ProducersProductsSerializer(category, context={'request': request})
        return Response(serializer.data)

    def delete(self, request, pk):
        category = get_object_or_404(ProducersProducts, pk=pk)
        category.soft_delete()
        return Response({"success": "Producers products deleted successfully"}, status=status.HTTP_200_OK)
    

