from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from rest_framework.authentication import TokenAuthentication from .serializers import AccountSerializer, AccountCreateSerializer,AccountUpdateSerializer from .models import Account from drf_yasg import openapi from drf_yasg.utils import swagger_auto_schema from rest_framework import status from rest_framework_simplejwt.authentication import JWTAuthentication from django.db.models import Sum class AccountlistAPIView(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] @swagger_auto_schema( operation_summary="Get My Accounts", operation_description="Retrieve current user's accounts.", responses={ 200: AccountSerializer(many=True), }, tags=["Accounts"], ) def get(self, request): accounts = Account.objects.filter( user=request.user ) serializer = AccountSerializer( accounts, many=True ) return Response( serializer.data, status=status.HTTP_200_OK ) class AccountCreateAPIView(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] @swagger_auto_schema( operation_summary="Create Account", operation_description="Create a new account.", request_body=AccountCreateSerializer, responses={ 201: AccountSerializer, 400: "Bad Request", }, tags=["Accounts"], ) def post(self, request): serializer = AccountCreateSerializer(data=request.data) if serializer.is_valid(): account = serializer.save(user=request.user) response_serializer = AccountSerializer(account) return Response( response_serializer.data, status=status.HTTP_201_CREATED ) return Response( serializer.errors, status=status.HTTP_400_BAD_REQUEST ) class AccountDetailAPIView(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] @swagger_auto_schema( operation_summary="Get Account", operation_description="Retrieve current user's account by ID.", manual_parameters=[ openapi.Parameter( "id", openapi.IN_PATH, description="Account ID", type=openapi.TYPE_INTEGER, required=True ) ], responses={ 200: AccountSerializer, 404: "Account not found", }, tags=["Accounts"], ) def get(self, request, id): try: account = Account.objects.get( id=id, user=request.user ) except Account.DoesNotExist: return Response( { "message": "Account not found" }, status=status.HTTP_404_NOT_FOUND ) serializer = AccountSerializer(account) return Response( serializer.data, status=status.HTTP_200_OK ) class AccountUpdateAPIView(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] @swagger_auto_schema( operation_summary="Update Account", operation_description="Update one of current user's accounts.", request_body=AccountUpdateSerializer, responses={ 200: AccountSerializer, 400: "Bad Request", 404: "Account Not Found", }, tags=["Accounts"], ) def put(self, request): account_id = request.data.get("id") try: account = Account.objects.get( id=account_id, user=request.user ) except Account.DoesNotExist: return Response( {"message": "Account not found"}, status=status.HTTP_404_NOT_FOUND ) serializer = AccountSerializer( account, data=request.data, partial=True ) if serializer.is_valid(): serializer.save() return Response( serializer.data, status=status.HTTP_200_OK ) return Response( serializer.errors, status=status.HTTP_400_BAD_REQUEST ) class AccountDeleteAPIView(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] @swagger_auto_schema( operation_summary="Delete Account", operation_description="Delete an account by id from request body", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, required=[ "id" ], properties={ "id": openapi.Schema( type=openapi.TYPE_INTEGER, description="Account ID", example=2 ) } ), responses={ 204: openapi.Response( description="Account deleted successfully" ), 404: openapi.Response( description="Account not found" ) }, tags=["Accounts"] ) def delete(self, request): account_id = request.data.get("id") try: account = Account.objects.get( id=account_id, user=request.user ) except Account.DoesNotExist: return Response( { "message": "Account not found" }, status=status.HTTP_404_NOT_FOUND ) account.delete() return Response( { "message": "Account deleted successfully" }, status=status.HTTP_202_ACCEPTED ) class AccountBalanceAPIView(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] @swagger_auto_schema( operation_summary="Get Account Balance", operation_description="Get current user's account balance using JWT token.", responses={ 200: openapi.Response( description="Account balance retrieved successfully", schema=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ "account_number": openapi.Schema( type=openapi.TYPE_STRING ), "balance": openapi.Schema( type=openapi.TYPE_INTEGER ), } ) ), 404: openapi.Response( description="Account not found" ) }, tags=["Accounts"] ) def get(self, request): total_balance = ( Account.objects.filter(user=request.user) .aggregate(total=Sum("balance"))["total"] or 0 ) return Response( { "total_balance": total_balance }, status=status.HTTP_200_OK )