from decimal import Decimal

from django.db.models import Sum
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.accounts.models import User
from apps.common.permissions import IsAdmin
from apps.ledger import services as ledger
from apps.ledger.models import Transaction
from apps.orders.models import Order
from apps.payouts.models import Payout

ZERO = Decimal('0.00')


def _f(value) -> float:
    return float(value or ZERO)


class EarningsView(APIView):
    """GET /earnings/:userId — earnings breakdown derived from the ledger."""

    permission_classes = [IsAuthenticated]

    def get(self, request, user_id):
        if request.user.role != 'admin' and request.user.id != int(user_id):
            return Response({'error': 'Forbidden'}, status=403)
        user = User.objects.filter(pk=user_id).first()
        if not user:
            return Response({'error': 'User not found'}, status=404)

        breakdown = ledger.wallet_breakdown(user)
        sales = (breakdown.get(Transaction.Kind.COMMISSION, ZERO)
                 + breakdown.get(Transaction.Kind.COMMISSION_REVERSAL, ZERO))
        task = breakdown.get(Transaction.Kind.TASK, ZERO)
        referral = breakdown.get(Transaction.Kind.REFERRAL, ZERO)
        reward = breakdown.get(Transaction.Kind.REWARD, ZERO)

        # Pending = commission on live orders that hasn't been posted yet.
        pending = (Order.objects
                   .filter(user=user, status__in=Order.PENDING_EARNING,
                           commission_posted=False)
                   .aggregate(s=Sum('commission'))['s'] or ZERO)

        paid_out = (Payout.objects
                    .filter(user=user, status=Payout.Status.PAID)
                    .aggregate(s=Sum('amount'))['s'] or ZERO)

        total_earned = sales + task + referral + reward
        total_balance = ledger.user_wallet_balance(user)  # available to withdraw

        return Response({
            'task_earnings': _f(task),
            'sales_earnings': _f(sales),
            'pending_sales_earnings': _f(pending),
            'referral_earnings': _f(referral),
            'reward_earnings': _f(reward),
            'total_earned': _f(total_earned),
            'total_paid_out': _f(paid_out),
            'total_balance': _f(total_balance),
        })


class StatsView(APIView):
    """GET /stats — platform-wide admin dashboard metrics."""

    permission_classes = [IsAdmin]

    def get(self, request):
        active_states = list(Order.PENDING_EARNING)
        total_sales = (Order.objects
                       .exclude(status=Order.Status.CANCELLED)
                       .aggregate(s=Sum('selling_price'))['s'] or ZERO)
        sales_commission = (Order.objects
                            .filter(commission_posted=True)
                            .aggregate(s=Sum('commission'))['s'] or ZERO)

        return Response({
            'total_users': User.objects.filter(role='user').count(),
            'total_tasks': 0,  # tasks module ships in phase 2
            'total_sales': _f(total_sales),
            'total_earnings': _f(sales_commission),
            'task_earnings': 0,
            'sales_earnings': _f(sales_commission),
            'referral_earnings': 0,
            'pending_orders': Order.objects.filter(status=Order.Status.PENDING_REVIEW).count(),
            'active_orders': Order.objects.filter(status__in=active_states).count(),
        })
