from decimal import Decimal, InvalidOperation

from rest_framework import permissions, serializers, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from .models import Goal
from .serializers import GoalSerializer


class GoalViewSet(viewsets.ModelViewSet):
    serializer_class = GoalSerializer
    permission_classes = [permissions.IsAuthenticated]
    filterset_fields = ['category']

    def get_queryset(self):
        return Goal.objects.filter(user=self.request.user)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

    @action(detail=True, methods=['post'])
    def contribute(self, request, pk=None):
        """Add a contribution toward this goal (bumps current_amount)."""
        goal = self.get_object()
        try:
            amount = Decimal(str(request.data.get('amount')))
        except (InvalidOperation, TypeError):
            raise serializers.ValidationError({'amount': 'Enter a valid amount.'})
        if amount == 0:
            raise serializers.ValidationError({'amount': 'Amount cannot be zero.'})

        new_total = goal.current_amount + amount
        # Allow withdrawals (negative), but never below zero.
        goal.current_amount = max(Decimal('0'), new_total)
        goal.save(update_fields=['current_amount', 'updated_at'])
        return Response(GoalSerializer(goal).data)
