from rest_framework import generics, status, filters
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from django_filters.rest_framework import DjangoFilterBackend
from django.shortcuts import get_object_or_404
from django.db.models import Q, Avg
from django.db import models
from django.conf import settings

from .models import Service, ServiceFeature, ServiceCategory
from .serializers import (
    ServiceSerializer, 
    ServiceListSerializer, 
    ServiceCreateUpdateSerializer,
    ServiceFeatureSerializer,
    ServiceCategorySerializer
)


class ServiceListView(generics.ListAPIView):
    """
    List all active services with optional filtering
    """
    queryset = Service.objects.filter(is_active=True)
    serializer_class = ServiceListSerializer
    permission_classes = [AllowAny]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['featured', 'display_order']
    search_fields = ['title', 'description']
    ordering_fields = ['display_order', 'created_at', 'title', 'price']
    ordering = ['display_order', 'created_at']

    def get_queryset(self):
        queryset = super().get_queryset()
        
        # Filter by category if provided
        category_slug = self.request.query_params.get('category', None)
        if category_slug:
            queryset = queryset.filter(category__slug=category_slug)
            
        # Filter by price range if provided
        min_price = self.request.query_params.get('min_price', None)
        max_price = self.request.query_params.get('max_price', None)
        
        if min_price:
            queryset = queryset.filter(price__gte=min_price)
        if max_price:
            queryset = queryset.filter(price__lte=max_price)
            
        return queryset


class ServiceDetailView(generics.RetrieveAPIView):
    """
    Retrieve a single service by slug
    """
    queryset = Service.objects.filter(is_active=True)
    serializer_class = ServiceSerializer
    permission_classes = [AllowAny]
    lookup_field = 'slug'


class ServiceCreateView(generics.CreateAPIView):
    """
    Create a new service (admin only)
    """
    queryset = Service.objects.all()
    serializer_class = ServiceCreateUpdateSerializer
    permission_classes = [IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser, JSONParser]


class ServiceUpdateView(generics.UpdateAPIView):
    """
    Update an existing service (admin only)
    """
    queryset = Service.objects.all()
    serializer_class = ServiceCreateUpdateSerializer
    permission_classes = [IsAuthenticated]
    lookup_field = 'slug'
    parser_classes = [MultiPartParser, FormParser, JSONParser]


class ServiceDeleteView(generics.DestroyAPIView):
    """
    Delete a service (admin only)
    """
    queryset = Service.objects.all()
    permission_classes = [IsAuthenticated]
    lookup_field = 'slug'

    def perform_destroy(self, instance):
        # Delete the image file if it exists
        if instance.image:
            instance.image.delete(save=False)
        instance.delete()


class FeaturedServicesView(generics.ListAPIView):
    """
    List all featured services
    """
    queryset = Service.objects.filter(is_active=True, featured=True)
    serializer_class = ServiceListSerializer
    permission_classes = [AllowAny]
    ordering = ['display_order', 'created_at']


class ServiceCategoryListView(generics.ListAPIView):
    """
    List all active service categories
    """
    queryset = ServiceCategory.objects.filter(is_active=True)
    serializer_class = ServiceCategorySerializer
    permission_classes = [AllowAny]
    ordering = ['display_order', 'name']


class ServiceCategoryDetailView(generics.RetrieveAPIView):
    """
    Retrieve a single service category by slug
    """
    queryset = ServiceCategory.objects.filter(is_active=True)
    serializer_class = ServiceCategorySerializer
    permission_classes = [AllowAny]
    lookup_field = 'slug'


@api_view(['GET'])
@permission_classes([AllowAny])
def service_search(request):
    """
    Search services by query string
    """
    query = request.GET.get('q', '')
    if not query:
        return Response({'error': 'Query parameter "q" is required'}, 
                       status=status.HTTP_400_BAD_REQUEST)
    
    services = Service.objects.filter(
        Q(is_active=True) & (
            Q(title__icontains=query) |
            Q(description__icontains=query) |
            Q(slug__icontains=query)
        )
    ).order_by('display_order', 'created_at')
    
    serializer = ServiceListSerializer(services, many=True)
    return Response({
        'query': query,
        'count': services.count(),
        'results': serializer.data
    })


@api_view(['GET'])
@permission_classes([AllowAny])
def service_stats(request):
    """
    Get service statistics
    """
    total_services = Service.objects.filter(is_active=True).count()
    featured_services = Service.objects.filter(is_active=True, featured=True).count()
    categories = ServiceCategory.objects.filter(is_active=True).count()
    
    # Average price
    services_with_price = Service.objects.filter(is_active=True, price__gt=0)
    avg_price = services_with_price.aggregate(avg_price=Avg('price'))['avg_price'] or 0
    
    return Response({
        'total_services': total_services,
        'featured_services': featured_services,
        'categories': categories,
        'average_price': float(avg_price)
    })


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def upload_service_image(request, slug):
    """
    Upload an image for a specific service (admin only)
    """
    try:
        service = get_object_or_404(Service, slug=slug)
        
        if 'image' not in request.FILES:
            return Response(
                {'error': 'No image file provided'}, 
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # Delete old image if it exists
        if service.image:
            service.image.delete(save=False)
        
        # Save new image
        service.image = request.FILES['image']
        service.save()
        
        serializer = ServiceSerializer(service)
        return Response({
            'message': 'Image uploaded successfully',
            'service': serializer.data
        })
        
    except Exception as e:
        return Response(
            {'error': f'Failed to upload image: {str(e)}'}, 
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )