from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from django.utils import timezone
from datetime import timedelta
from decimal import Decimal
from django.db import transaction
from django.db.models import Sum

from .models import DailyWorkClaim
from .serializers import (
    DailyWorkClaimSerializer, 
    DailyWorkStatusSerializer,
    DailyWorkHistorySerializer
)

class DailyCheckViewSet(viewsets.ViewSet):
    permission_classes = [IsAuthenticated]
    
    def get_profile(self, request):
        """Get user profile"""
        try:
            return request.user.profile
        except:
            return None
    
    @action(detail=False, methods=['get'])
    def status(self, request):
        """Check if user can claim today"""
        profile = self.get_profile(request)
        if not profile:
            return Response(
                {'error': 'Profile not found'}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        today = timezone.now().date()
        claimed_today = DailyWorkClaim.objects.filter(
            profile=profile,
            claim_date=today
        ).exists()
        
        last_claim = DailyWorkClaim.objects.filter(
            profile=profile
        ).first()
        
        next_claim_time = None
        if last_claim and claimed_today:
            next_claim_time = last_claim.claimed_at + timedelta(days=1)
        
        data = {
            'can_claim': not claimed_today,
            'next_claim_time': next_claim_time,
            'claimed_today': claimed_today,
            'reward_amount': Decimal('0.0001')
        }
        
        serializer = DailyWorkStatusSerializer(data)
        return Response(serializer.data)
    
    @action(detail=False, methods=['post'])
    def claim(self, request):
        """Claim daily reward"""
        profile = self.get_profile(request)
        if not profile:
            return Response(
                {'error': 'Profile not found'}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        today = timezone.now().date()
        claimed_today = DailyWorkClaim.objects.filter(
            profile=profile,
            claim_date=today
        ).exists()
        
        if claimed_today:
            return Response(
                {'error': 'You have already claimed today'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            with transaction.atomic():
                # Create claim
                claim = DailyWorkClaim.objects.create(
                    profile=profile,
                    reward_amount=Decimal('0.0001'),
                    claim_date=today
                )
                
                # Update balance
                profile.balance += Decimal('0.0001')
                profile.save()
                
                # Serialize the claim
                claim_serializer = DailyWorkClaimSerializer(claim)
                
                # Return response directly
                return Response({
                    'success': True,
                    'message': 'Daily reward claimed successfully',
                    'claim': claim_serializer.data,
                    'new_balance': profile.balance,
                    'reward_amount': Decimal('0.0001')
                }, status=status.HTTP_200_OK)
                
        except Exception as e:
            return Response(
                {'error': f'Failed to claim: {str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def history(self, request):
        """Get claim history"""
        profile = self.get_profile(request)
        if not profile:
            return Response(
                {'error': 'Profile not found'}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        # Get all claims
        claims = DailyWorkClaim.objects.filter(
            profile=profile
        ).order_by('-claimed_at')
        
        # Calculate statistics
        total_claims = claims.count()
        total_amount = claims.aggregate(total=Sum('reward_amount'))['total'] or Decimal('0.0000')
        
        # Serialize claims
        claim_serializer = DailyWorkClaimSerializer(claims, many=True)
        
        # Prepare response
        response_data = {
            'history': claim_serializer.data,
            'statistics': {
                'total_claims': total_claims,
                'total_amount': str(total_amount),  # Convert to string for JSON
                'last_claim': claim_serializer.data[0] if claims.exists() else None
            }
        }
        
        return Response(response_data)  # Return directly, no need for another serializer
    
    @action(detail=False, methods=['get'])
    def last_claim(self, request):
        """Get last claim"""
        profile = self.get_profile(request)
        if not profile:
            return Response(
                {'error': 'Profile not found'}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        last_claim = DailyWorkClaim.objects.filter(
            profile=profile
        ).first()
        
        if last_claim:
            serializer = DailyWorkClaimSerializer(last_claim)
            return Response(serializer.data)
        else:
            return Response(
                {'message': 'No claims found'}, 
                status=status.HTTP_404_NOT_FOUND
            )
    
    @action(detail=False, methods=['get'])
    def stats(self, request):
        """Get detailed statistics"""
        profile = self.get_profile(request)
        if not profile:
            return Response(
                {'error': 'Profile not found'}, 
                status=status.HTTP_404_NOT_FOUND
            )
        
        claims = DailyWorkClaim.objects.filter(profile=profile)
        
        # This week
        week_start = timezone.now().date() - timedelta(days=7)
        this_week = claims.filter(claim_date__gte=week_start).count()
        
        # This month
        month_start = timezone.now().replace(day=1).date()
        this_month = claims.filter(claim_date__gte=month_start).count()
        
        # Total
        total_claims = claims.count()
        total_amount = claims.aggregate(total=Sum('reward_amount'))['total'] or Decimal('0.0000')
        
        return Response({
            'total_claims': total_claims,
            'total_amount': f"{total_amount:.4f}",
            'this_week': this_week,
            'this_month': this_month,
            'average_per_day': round(total_claims / 30, 2) if total_claims > 0 else 0
        })