from rest_framework import generics, permissions, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from django.utils import timezone
from django.db.models import Q

from .models import (
    DistributorLevelProgress,
    FranchiseMonthlyIncentive,
    UserBonanzaCounter,
    RewardAchievement,
    Service,
    ServiceClaim,
    Gift,
    GiftClaim,
)
from .serializers import (
    DistributorLevelProgressSerializer,
    FranchiseMonthlyIncentiveSerializer,
    UserBonanzaCounterSerializer,
    RewardAchievementSerializer,
    ServiceSerializer,
    ServiceClaimSerializer,
    GiftSerializer,
    GiftClaimSerializer,
)

class DistributorLevelProgressListView(generics.ListAPIView):
    serializer_class = DistributorLevelProgressSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = DistributorLevelProgress.objects.all().order_by('-last_calculated_at')


class UserBonanzaCounterListCreateView(generics.ListCreateAPIView):
    serializer_class = UserBonanzaCounterSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = UserBonanzaCounter.objects.all().order_by('-updated_at')


class UserBonanzaCounterDetailView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = UserBonanzaCounterSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = UserBonanzaCounter.objects.all()


class FranchiseMonthlyIncentiveListCreateView(generics.ListCreateAPIView):
    serializer_class = FranchiseMonthlyIncentiveSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = FranchiseMonthlyIncentive.objects.all().order_by('-period_month', '-updated_at')


class FranchiseMonthlyIncentiveDetailView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = FranchiseMonthlyIncentiveSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = FranchiseMonthlyIncentive.objects.all()


# New Rewards Views

class RewardAchievementListView(generics.ListAPIView):
    """List user's rewards (supercoins earned after level achievement)"""
    serializer_class = RewardAchievementSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        user = self.request.user
        return RewardAchievement.objects.filter(user=user).order_by('-created_at')


class ServiceListView(generics.ListAPIView):
    """List available services/trips for user's current level"""
    serializer_class = ServiceSerializer
    permission_classes = [permissions.IsAuthenticated]
    queryset = Service.objects.filter(is_active=True).order_by('level', 'service_name')

    def get_queryset(self):
        # Get user's highest level
        from apps.business.rewards.models import RewardAchievement
        highest_level = RewardAchievement.objects.filter(
            user=self.request.user,
            status='earned'
        ).order_by('-level').values_list('level', flat=True).first() or 0
        
        # Return services up to user's level
        return Service.objects.filter(
            is_active=True,
            level__lte=highest_level
        ).order_by('level', 'service_name')


class ServiceClaimCreateView(generics.CreateAPIView):
    """User claims a service/trip"""
    serializer_class = ServiceClaimSerializer
    permission_classes = [permissions.IsAuthenticated]

    def perform_create(self, serializer):
        # Ensure user can only claim for themselves
        serializer.save(user=self.request.user)


class ServiceClaimListView(generics.ListAPIView):
    """List user's service claims"""
    serializer_class = ServiceClaimSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return ServiceClaim.objects.filter(user=self.request.user).order_by('-created_at')


class ServiceClaimDetailView(generics.RetrieveUpdateAPIView):
    """Retrieve/Update service claim"""
    serializer_class = ServiceClaimSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return ServiceClaim.objects.filter(user=self.request.user)

    def perform_update(self, serializer):
        # Only allow updating notes on user side
        instance = self.get_object()
        if 'notes' in self.request.data:
            serializer.save()
        else:
            serializer.save()


# Admin views for approving/updating service claims
class AdminServiceClaimListView(generics.ListAPIView):
    """Admin: List all service claims pending approval"""
    serializer_class = ServiceClaimSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = ServiceClaim.objects.all().order_by('-created_at')


class AdminServiceClaimApproveView(generics.UpdateAPIView):
    """Admin: Approve a service claim"""
    serializer_class = ServiceClaimSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = ServiceClaim.objects.all()

    def perform_update(self, serializer):
        instance = self.get_object()
        instance.status = 'approved'
        instance.approved_by = self.request.user
        instance.approved_at = timezone.now()
        if 'admin_notes' in self.request.data:
            instance.admin_notes = self.request.data['admin_notes']
        instance.save()
        serializer.save()


class AdminServiceClaimCompleteView(generics.UpdateAPIView):
    """Admin: Mark service claim as completed"""
    serializer_class = ServiceClaimSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = ServiceClaim.objects.all()

    def perform_update(self, serializer):
        instance = self.get_object()
        instance.status = 'completed'
        instance.completed_at = timezone.now()
        if 'admin_notes' in self.request.data:
            instance.admin_notes = self.request.data['admin_notes']
        instance.save()
        # Update service claimed_count
        instance.service.claimed_count += 1
        instance.service.save(update_fields=['claimed_count'])
        serializer.save()


class AdminServiceClaimRejectView(generics.UpdateAPIView):
    """Admin: Reject a service claim"""
    serializer_class = ServiceClaimSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = ServiceClaim.objects.all()

    def perform_update(self, serializer):
        instance = self.get_object()
        instance.status = 'rejected'
        if 'admin_notes' in self.request.data:
            instance.admin_notes = self.request.data['admin_notes']
        instance.save()
        serializer.save()


# Gift Views
class GiftListView(generics.ListAPIView):
    """List available gifts for user's current level"""
    serializer_class = GiftSerializer
    permission_classes = [permissions.IsAuthenticated]
    queryset = Gift.objects.filter(is_active=True).order_by('level', 'gift_name')

    def get_queryset(self):
        # Get user's highest level
        from apps.business.rewards.models import RewardAchievement
        highest_level = RewardAchievement.objects.filter(
            user=self.request.user,
            status='earned'
        ).order_by('-level').values_list('level', flat=True).first() or 0
        
        # Return gifts up to user's level
        return Gift.objects.filter(
            is_active=True,
            level__lte=highest_level
        ).order_by('level', 'gift_name')


class GiftClaimCreateView(generics.CreateAPIView):
    """User claims a gift"""
    serializer_class = GiftClaimSerializer
    permission_classes = [permissions.IsAuthenticated]

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)


class GiftClaimListView(generics.ListAPIView):
    """List user's gift claims"""
    serializer_class = GiftClaimSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return GiftClaim.objects.filter(user=self.request.user).order_by('-created_at')


class GiftClaimDetailView(generics.RetrieveUpdateAPIView):
    """Retrieve/Update gift claim"""
    serializer_class = GiftClaimSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return GiftClaim.objects.filter(user=self.request.user)


# Admin views for approving/updating gift claims
class AdminGiftClaimListView(generics.ListAPIView):
    """Admin: List all gift claims pending approval"""
    serializer_class = GiftClaimSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = GiftClaim.objects.all().order_by('-created_at')


class AdminGiftClaimApproveView(generics.UpdateAPIView):
    """Admin: Approve a gift claim"""
    serializer_class = GiftClaimSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = GiftClaim.objects.all()

    def perform_update(self, serializer):
        instance = self.get_object()
        instance.status = 'approved'
        instance.approved_by = self.request.user
        instance.approved_at = timezone.now()
        if 'admin_notes' in self.request.data:
            instance.admin_notes = self.request.data['admin_notes']
        instance.save()
        serializer.save()


class AdminGiftClaimCompleteView(generics.UpdateAPIView):
    """Admin: Mark gift claim as completed"""
    serializer_class = GiftClaimSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = GiftClaim.objects.all()

    def perform_update(self, serializer):
        instance = self.get_object()
        instance.status = 'completed'
        instance.completed_at = timezone.now()
        if 'admin_notes' in self.request.data:
            instance.admin_notes = self.request.data['admin_notes']
        instance.save()
        # Update gift claimed_count
        instance.gift.claimed_count += 1
        instance.gift.save(update_fields=['claimed_count'])
        serializer.save()


class AdminGiftClaimRejectView(generics.UpdateAPIView):
    """Admin: Reject a gift claim"""
    serializer_class = GiftClaimSerializer
    permission_classes = [permissions.IsAdminUser]
    queryset = GiftClaim.objects.all()

    def perform_update(self, serializer):
        instance = self.get_object()
        instance.status = 'rejected'
        if 'admin_notes' in self.request.data:
            instance.admin_notes = self.request.data['admin_notes']
        instance.save()
        serializer.save()
