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

"""
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpRequest, HttpResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _
from django.views.generic.base import View

from ema.forms import NewEmaForm, EditEmaForm
from ema.models import Ema
from ema.tables import EmaTable
from konova.contexts import BaseContext
from konova.decorators import shared_access_required, conservation_office_group_required
from konova.forms import SimpleGeomForm
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import RECORDED_BLOCKS_EDIT, IDENTIFIER_REPLACED, FORM_INVALID, \
    GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE
from konova.views.identifier import AbstractIdentifierGeneratorView
from konova.views.index import AbstractIndexView


class IndexEmaView(AbstractIndexView):
    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        """ Renders the index view for EMAs

        Args:
            request (HttpRequest): The incoming request

        Returns:

        """
        emas = Ema.objects.filter(
            deleted=None,
        ).order_by(
            "-modified__timestamp"
        )

        table = EmaTable(
            request,
            queryset=emas
        )
        context = {
            "table": table,
            TAB_TITLE_IDENTIFIER: _("EMAs - Overview"),
        }
        context = BaseContext(request, context).context
        return render(request, self._TEMPLATE, context)

class NewEmaView(LoginRequiredMixin, View):
    _TEMPLATE = "ema/form/view.html"

    @method_decorator(conservation_office_group_required)
    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        """ GET endpoint

        Renders form for new EMA

        Args:
            request (HttpRequest): The incoming request
            *args ():
            **kwargs ():

        Returns:

        """
        data_form = NewEmaForm(request.POST or None)
        geom_form = SimpleGeomForm(request.POST or None, read_only=False)
        context = {
            "form": data_form,
            "geom_form": geom_form,
            TAB_TITLE_IDENTIFIER: _("New EMA"),
        }
        context = BaseContext(request, context).context
        return render(request, self._TEMPLATE, context)

    @method_decorator(conservation_office_group_required)
    def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        """ POST endpoint

        Processes submitted form

        Args:
            request (HttpRequest): The incoming request
            *args ():
            **kwargs ():

        Returns:

        """
        data_form = NewEmaForm(request.POST or None)
        geom_form = SimpleGeomForm(request.POST or None, read_only=False)
        if data_form.is_valid() and geom_form.is_valid():
            generated_identifier = data_form.cleaned_data.get("identifier", None)
            ema = data_form.save(request.user, geom_form)
            if generated_identifier != ema.identifier:
                messages.info(
                    request,
                    IDENTIFIER_REPLACED.format(
                        generated_identifier,
                        ema.identifier
                    )
                )
            messages.success(request, _("EMA {} added").format(ema.identifier))
            if geom_form.has_geometry_simplified():
                messages.info(
                    request,
                    GEOMETRY_SIMPLIFIED
                )
            num_ignored_geometries = geom_form.get_num_geometries_ignored()
            if num_ignored_geometries > 0:
                messages.info(
                    request,
                    GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries)
                )
            return redirect("ema:detail", id=ema.id)
        else:
            messages.error(request, FORM_INVALID, extra_tags="danger",)
        context = {
            "form": data_form,
            "geom_form": geom_form,
            TAB_TITLE_IDENTIFIER: _("New EMA"),
        }
        context = BaseContext(request, context).context
        return render(request, self._TEMPLATE, context)

class EmaIdentifierGeneratorView(AbstractIdentifierGeneratorView):
    _MODEL = Ema

    @method_decorator(conservation_office_group_required)
    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        return super().get(request, *args, **kwargs)

class EditEmaView(LoginRequiredMixin, View):
    _TEMPLATE = "compensation/form/view.html"

    @method_decorator(conservation_office_group_required)
    @method_decorator(shared_access_required(Ema, "id"))
    def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse:
        """ GET endpoint

        Renders form

        Args:
            request (HttpRequest): The incoming request
            id (str): The ema identifier
            *args ():
            **kwargs ():

        Returns:

        """
        # Get object from db
        ema = get_object_or_404(Ema, id=id)
        if ema.is_recorded:
            messages.info(
                request,
                RECORDED_BLOCKS_EDIT
            )
            return redirect("ema:detail", id=id)

        # Create forms, initialize with values from db/from POST request
        data_form = EditEmaForm(instance=ema)
        geom_form = SimpleGeomForm(read_only=False, instance=ema)
        context = {
            "form": data_form,
            "geom_form": geom_form,
            TAB_TITLE_IDENTIFIER: _("Edit {}").format(ema.identifier),
        }
        context = BaseContext(request, context).context
        return render(request, self._TEMPLATE, context)

    @method_decorator(conservation_office_group_required)
    @method_decorator(shared_access_required(Ema, "id"))
    def post(self, request: HttpRequest, id:str, *args, **kwargs) -> HttpResponse:
        """ POST endpoint

        Process submitted forms

        Args:
            request (HttpRequest): The incoming request
            id (str): The id of the ema
            *args ():
            **kwargs ():

        Returns:

        """
        # Get object from db
        ema = get_object_or_404(Ema, id=id)
        if ema.is_recorded:
            messages.info(
                request,
                RECORDED_BLOCKS_EDIT
            )
            return redirect("ema:detail", id=id)

        # Create forms, initialize with values from db/from POST request
        data_form = EditEmaForm(request.POST or None, instance=ema)
        geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=ema)
        if data_form.is_valid() and geom_form.is_valid():
            # The data form takes the geom form for processing, as well as the performing user
            ema = data_form.save(request.user, geom_form)
            messages.success(request, _("EMA {} edited").format(ema.identifier))
            if geom_form.has_geometry_simplified():
                messages.info(
                    request,
                    GEOMETRY_SIMPLIFIED
                )
            num_ignored_geometries = geom_form.get_num_geometries_ignored()
            if num_ignored_geometries > 0:
                messages.info(
                    request,
                    GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries)
                )
            return redirect("ema:detail", id=ema.id)
        else:
            messages.error(request, FORM_INVALID, extra_tags="danger", )
        context = {
            "form": data_form,
            "geom_form": geom_form,
            TAB_TITLE_IDENTIFIER: _("Edit {}").format(ema.identifier),
        }
        context = BaseContext(request, context).context
        return render(request, self._TEMPLATE, context)
