from rest_framework.decorators import action
from rest_framework import status
from django.db import transaction
from apps.profiles.models import Profile, ProfilePackage
from .models import Package
from .serializers import PackageSerializer
from apps.core.views.base import BaseViewSet
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from django.utils import timezone
from datetime import timedelta

class PackageViewSet(BaseViewSet):
    queryset = Package.objects.all()
    serializer_class = PackageSerializer
    
    permission_app_name = 'package'
    permission_model_name = 'package'
    view_permissions = ["list", "create", "update", "toggle_status", "partial_update", "retrieve", "destroy","subscribe", "unsubscribe",'history']  
    
    filterset_fields = ['is_active', 'price']
    search_fields = ['name']

    def get_permissions(self):
        if self.action == 'list':
            return [AllowAny()]
        return [IsAuthenticated()] 


    @action(detail=True, methods=['get','post'])
    def subscribe(self, request, pk=None):
        try:
            user = request.user
            package = self.get_object()
            profile, _ = Profile.objects.get_or_create(user=user)

            if not package.is_active:
                return Response({"message": "This package is inactive"}, status=400)

            if profile.balance < package.price:
                return Response({"message": "Insufficient balance"}, status=400)

            existing_sub = ProfilePackage.objects.filter(profile=profile, package=package).first()
            if existing_sub and not existing_sub.is_expired():
                return Response({"message": f"Already active until {existing_sub.expires_at}"}, status=400)

            with transaction.atomic():
                profile.balance -= package.price
                profile.save()
                expiry_date = timezone.now() + timedelta(days=30)
                ProfilePackage.objects.update_or_create(
                    profile=profile, 
                    package=package,
                    defaults={'expires_at': expiry_date, 'subscribed_at': timezone.now()}
                )

                profile.distribute_commission(package.price)

            return Response({
                "success": True,
                "message": f"Successfully subscribed for 30 days. Expires on: {expiry_date.date()}",
                "balance": str(profile.balance)
            })

        except Exception as e:
            return Response({"error": str(e)}, status=500)

    @action(detail=True, methods=['post', 'delete', 'get'])
    def unsubscribe(self, request, pk=None):
        try:
            user = request.user
            package = self.get_object()
            
            if not hasattr(user, 'profile'):
                return Response({
                    "success": False,
                    "message": "You don't have any profile or subscriptions",
                    "error_code": "4042"
                }, status=status.HTTP_404_NOT_FOUND)
            
            profile = user.profile
            
            if not profile.packages.filter(id=package.id).exists():
                return Response({
                    "success": False,
                    "message": "You are not subscribed to this package",
                    "error_code": "4004"
                }, status=status.HTTP_400_BAD_REQUEST)
            
            with transaction.atomic():
                profile.packages.remove(package)
            
            return Response({
                "success": True,
                "message": f"Successfully unsubscribed from {package.name}",
                "data": {
                    "package_id": str(package.id),
                    "package_name": package.name
                }
            }, status=status.HTTP_200_OK)
            
        except Exception as e:
            return Response({
                "success": False,
                "message": "Internal server error",
                "error_code":"500"
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        


