"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 22.08.22

"""
from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.views import View

from intervention.forms.modals.deduction import NewEcoAccountDeductionModalForm, EditEcoAccountDeductionModalForm, \
    RemoveEcoAccountDeductionModalForm
from konova.utils.message_templates import DEDUCTION_ADDED, DEDUCTION_EDITED, DEDUCTION_REMOVED, DEDUCTION_UNKNOWN


class AbstractDeductionView(View):
    model = None
    redirect_url = None

    def _custom_check(self, obj):
        """
        Can be used by inheriting classes to provide custom checks before further processing

        """
        raise NotImplementedError("Must be implemented in subclasses")


class AbstractNewDeductionView(AbstractDeductionView):

    class Meta:
        abstract = True

    def get(self, request, id: str):
        """ Renders a modal form view for creating deductions

        Args:
            request (HttpRequest): The incoming request
            id (str): The obj's id which shall benefit from this deduction

        Returns:

        """
        obj = get_object_or_404(self.model, id=id)
        self._custom_check(obj)
        form = NewEcoAccountDeductionModalForm(request.POST or None, instance=obj, request=request)
        return form.process_request(
            request,
            msg_success=DEDUCTION_ADDED,
            redirect_url=reverse(self.redirect_url, args=(id,)) + "#related_data",
        )

    def post(self, request, id: str):
        return self.get(request, id)


class AbstractEditDeductionView(AbstractDeductionView):

    def _custom_check(self, obj):
        pass

    class Meta:
        abstract = True

    def get(self, request, id: str, deduction_id: str):
        """ Renders a modal view for editing deductions

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

        Returns:

        """
        obj = get_object_or_404(self.model, id=id)
        self._custom_check(obj)
        try:
            eco_deduction = obj.deductions.get(id=deduction_id)
        except ObjectDoesNotExist:
            raise Http404(DEDUCTION_UNKNOWN)

        form = EditEcoAccountDeductionModalForm(request.POST or None, instance=obj, deduction=eco_deduction,
                                                request=request)
        return form.process_request(
            request=request,
            msg_success=DEDUCTION_EDITED,
            redirect_url=reverse(self.redirect_url, args=(id,)) + "#related_data"
        )

    def post(self, request, id: str, deduction_id: str):
        return self.get(request, id, deduction_id)


class AbstractRemoveDeductionView(AbstractDeductionView):

    def _custom_check(self, obj):
        pass

    class Meta:
        abstract = True

    def get(self, request, id: str, deduction_id: str):
        """ Renders a modal view for removing deductions

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

        Returns:

        """
        obj = get_object_or_404(self.model, id=id)
        self._custom_check(obj)
        try:
            eco_deduction = obj.deductions.get(id=deduction_id)
        except ObjectDoesNotExist:
            raise Http404(DEDUCTION_UNKNOWN)
        form = RemoveEcoAccountDeductionModalForm(request.POST or None, instance=obj, deduction=eco_deduction,
                                                  request=request)
        return form.process_request(
            request=request,
            msg_success=DEDUCTION_REMOVED,
            redirect_url=reverse(self.redirect_url, args=(id,)) + "#related_data"
        )

    def post(self, request, id: str, deduction_id: str):
        return self.get(request, id, deduction_id)
