from django.db import transaction
from django.utils import timezone
from rest_framework import permissions, status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from accounting.models import Account, Transaction
from .models import Course, CourseFee, MemberCourse
from .serializers import CourseSerializer, CourseFeeSerializer, MemberCourseSerializer


class CourseViewSet(viewsets.ModelViewSet):
    queryset = Course.objects.prefetch_related('fees').all()
    serializer_class = CourseSerializer
    permission_classes = [permissions.IsAuthenticated]


class CourseFeeViewSet(viewsets.ModelViewSet):
    queryset = CourseFee.objects.select_related('course').all()
    serializer_class = CourseFeeSerializer
    permission_classes = [permissions.IsAuthenticated]


class MemberCourseViewSet(viewsets.ModelViewSet):
    queryset = MemberCourse.objects.select_related('member').all()
    serializer_class = MemberCourseSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        queryset = super().get_queryset()
        member_id = self.request.query_params.get('member')
        if member_id:
            queryset = queryset.filter(member_id=member_id)
        return queryset

    @action(detail=True, methods=['post'], url_path='pay')
    def pay(self, request, pk=None):
        member_course = self.get_object()

        try:
            amount = int(request.data.get('amount', 0))
            account_id = int(request.data.get('account', 0))
        except (TypeError, ValueError):
            return Response(
                {'detail': 'مبلغ و حساب پرداخت معتبر نیست.'},
                status=status.HTTP_400_BAD_REQUEST
            )

        payment_type = request.data.get('payment_type', 'cash')
        payment_types = {
            'cash': 'cash_payment',
            'pos': 'pos_payment',
            'transfer': 'transfer_payment',
        }

        if payment_type not in payment_types:
            return Response(
                {'detail': 'نوع پرداخت معتبر نیست.'},
                status=status.HTTP_400_BAD_REQUEST
            )

        if amount <= 0:
            return Response(
                {'detail': 'مبلغ پرداخت باید بیشتر از صفر باشد.'},
                status=status.HTTP_400_BAD_REQUEST
            )

        remaining = member_course.fee - member_course.paid_fee
        if amount > remaining:
            return Response(
                {'detail': 'مبلغ پرداخت بیشتر از بدهی دوره است.'},
                status=status.HTTP_400_BAD_REQUEST
            )

        try:
            account = Account.objects.get(id=account_id, is_active=True)
        except Account.DoesNotExist:
            return Response(
                {'detail': 'حساب مقصد پیدا نشد.'},
                status=status.HTTP_400_BAD_REQUEST
            )

        with transaction.atomic():
            setattr(
                member_course,
                payment_types[payment_type],
                getattr(member_course, payment_types[payment_type]) + amount
            )
            member_course.paid_fee += amount
            member_course.save(update_fields=[
                'paid_fee',
                payment_types[payment_type],
            ])

            Transaction.objects.create(
                account=account,
                transaction_type='income',
                amount=amount,
                description=f'پرداخت شهریه دوره - {member_course.member}',
                transaction_date=timezone.localdate(),
                created_by=request.user,
            )

        return Response(MemberCourseSerializer(member_course).data)
