from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status, viewsets
from django.db import transaction
from .models import Function
from .serializers import FunctionSerializer
from ErrorLogs.utils import log_error

# Create your views here.

@api_view(['GET', 'POST'])
def function_list(request):
    if request.method == 'GET':
        try:
            functions = Function.objects.all()
            serializer = FunctionSerializer(functions, many=True)
            return Response(serializer.data)
        except Exception as e:
            log_error('function_list.GET', e)
            return Response(
                {"error": "An error occurred while fetching functions"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    elif request.method == 'POST':
        try:
            with transaction.atomic():
                serializer = FunctionSerializer(data=request.data)
                if serializer.is_valid():
                    serializer.save()
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            log_error('function_list.POST', e)
            return Response(
                {"error": "An error occurred while creating function"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

@api_view(['GET', 'PUT', 'DELETE'])
def function_detail(request, pk):
    try:
        function = Function.objects.get(pk=pk)
    except Function.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        log_error('function_detail.get_function', e)
        return Response(
            {"error": "An error occurred while fetching function"},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR
        )

    if request.method == 'GET':
        try:
            serializer = FunctionSerializer(function)
            return Response(serializer.data)
        except Exception as e:
            log_error('function_detail.GET', e)
            return Response(
                {"error": "An error occurred while fetching function details"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    elif request.method == 'PUT':
        try:
            with transaction.atomic():
                serializer = FunctionSerializer(function, data=request.data)
                if serializer.is_valid():
                    serializer.save()
                    return Response(serializer.data)
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            log_error('function_detail.PUT', e)
            return Response(
                {"error": "An error occurred while updating function"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    elif request.method == 'DELETE':
        try:
            with transaction.atomic():
                function.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
        except Exception as e:
            log_error('function_detail.DELETE', e)
            return Response(
                {"error": "An error occurred while deleting function"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

class FunctionViewSet(viewsets.ModelViewSet):
    queryset = Function.objects.all()
    serializer_class = FunctionSerializer

    def list(self, request, *args, **kwargs):
        try:
            return super().list(request, *args, **kwargs)
        except Exception as e:
            log_error('FunctionViewSet.list', e)
            return Response(
                {"error": "An error occurred while fetching functions"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    def create(self, request, *args, **kwargs):
        try:
            with transaction.atomic():
                return super().create(request, *args, **kwargs)
        except Exception as e:
            log_error('FunctionViewSet.create', e)
            return Response(
                {"error": "An error occurred while creating function"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    def retrieve(self, request, *args, **kwargs):
        try:
            return super().retrieve(request, *args, **kwargs)
        except Exception as e:
            log_error('FunctionViewSet.retrieve', e)
            return Response(
                {"error": "An error occurred while fetching function details"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    def update(self, request, *args, **kwargs):
        try:
            with transaction.atomic():
                return super().update(request, *args, **kwargs)
        except Exception as e:
            log_error('FunctionViewSet.update', e)
            return Response(
                {"error": "An error occurred while updating function"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    def destroy(self, request, *args, **kwargs):
        try:
            with transaction.atomic():
                return super().destroy(request, *args, **kwargs)
        except Exception as e:
            log_error('FunctionViewSet.destroy', e)
            return Response(
                {"error": "An error occurred while deleting function"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
