"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 21.01.22

"""
import json

from django.http import JsonResponse, HttpRequest

from api.utils.serializer.v1.compensation import CompensationAPISerializerV1
from api.utils.serializer.v1.deduction import DeductionAPISerializerV1
from api.utils.serializer.v1.ecoaccount import EcoAccountAPISerializerV1
from api.utils.serializer.v1.ema import EmaAPISerializerV1
from api.utils.serializer.v1.intervention import InterventionAPISerializerV1
from api.views.views import AbstractAPIView


class AbstractAPIViewV1(AbstractAPIView):
    """ Holds general serialization functions for API v1

    """

    def __init__(self, *args, **kwargs):
        self.lookup = {
            "id": None,  # must be set in subclasses
            "deleted__isnull": True,
            "users__in": [],  # must be set in subclasses
        }
        super().__init__(*args, **kwargs)
        self.serializer = self.serializer()

    def get(self, request: HttpRequest, id=None):
        """ Handles the GET request

        Performs the fetching and serialization of the data

        Args:
            request (HttpRequest): The incoming request
            id (str): The entries id (optional)

        Returns:
            response (JsonResponse)
        """
        try:
            self.rpp = int(request.GET.get("rpp", self.rpp))
            self.page_number = int(request.GET.get("p", self.page_number))

            self.serializer.rpp = self.rpp
            self.serializer.page_number = self.page_number

            self.serializer.prepare_lookup(id, self.user)
            data = self.serializer.fetch_and_serialize()
        except Exception as e:
            return self._return_error_response(e, 500)
        return self._return_response(request, data)

    def post(self, request: HttpRequest):
        """ Handles the POST request

        Performs creation of new data

        Args:
            request (HttpRequest): The incoming request

        Returns:
            response (JsonResponse)
        """
        try:
            body = request.body.decode("utf-8")
            body = json.loads(body)
            created_id = self.serializer.create_model_from_json(body, self.user)
        except Exception as e:
            return self._return_error_response(e, 500)
        return JsonResponse({"id": created_id})

    def put(self, request: HttpRequest, id=None):
        """ Handles the PUT request

        Performs updating

        Args:
            request (HttpRequest): The incoming request
            id (str): The entries id

        Returns:
            response (JsonResponse)
        """
        try:
            body = request.body.decode("utf-8")
            body = json.loads(body)
            updated_id = self.serializer.update_model_from_json(id, body, self.user)
        except Exception as e:
            return self._return_error_response(e, 500)
        return JsonResponse({"id": updated_id})

    def delete(self, request: HttpRequest, id=None):
        """ Handles a DELETE request

        Args:
            request (HttpRequest): The incoming request
            id (str): The object's id

        Returns:
            response (JsonResponse)
        """

        try:
            success = self.serializer.delete_entry(id, self.user)
        except Exception as e:
            return self._return_error_response(e, 500)
        return JsonResponse(
            {
                "success": success,
            }
        )


class InterventionAPIViewV1(AbstractAPIViewV1):
    serializer = InterventionAPISerializerV1


class CompensationAPIViewV1(AbstractAPIViewV1):
    serializer = CompensationAPISerializerV1


class EcoAccountAPIViewV1(AbstractAPIViewV1):
    serializer = EcoAccountAPISerializerV1


class EmaAPIViewV1(AbstractAPIViewV1):
    serializer = EmaAPISerializerV1


class DeductionAPIViewV1(AbstractAPIViewV1):
    serializer = DeductionAPISerializerV1