"""
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.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 import View

from compensation.forms.eco_account import EditEcoAccountForm, NewEcoAccountForm
from compensation.models import EcoAccount
from compensation.tables.eco_account import EcoAccountTable
from konova.contexts import BaseContext
from konova.decorators import shared_access_required, default_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, FORM_INVALID, \
    IDENTIFIER_REPLACED, GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE
from konova.views.identifier import AbstractIdentifierGeneratorView
from konova.views.index import AbstractIndexView


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

        Args:
            request (HttpRequest): The incoming request

        Returns:
            A rendered view
        """
        eco_accounts = EcoAccount.objects.filter(
            deleted=None,
        ).order_by(
            "-modified__timestamp"
        )
        table = EcoAccountTable(
            request=request,
            queryset=eco_accounts
        )
        context = {
            "table": table,
            TAB_TITLE_IDENTIFIER: _("Eco-account - Overview"),
        }
        context = BaseContext(request, context).context
        return render(request, self._TEMPLATE, context)


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

    @method_decorator(default_group_required)
    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        """
        Renders a view for a new eco account creation

        Args:
            request (HttpRequest): The incoming request

        Returns:

        """
        data_form = NewEcoAccountForm(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 Eco-Account"),
        }
        context = BaseContext(request, context).context

        return render(request, self._TEMPLATE, context)

    @method_decorator(default_group_required)
    def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:

        """
        Renders a view for a new eco account creation

        Args:
            request (HttpRequest): The incoming request

        Returns:

        """
        data_form = NewEcoAccountForm(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)
            acc = data_form.save(request.user, geom_form)
            if generated_identifier != acc.identifier:
                messages.info(
                    request,
                    IDENTIFIER_REPLACED.format(
                        generated_identifier,
                        acc.identifier
                    )
                )
            messages.success(request, _("Eco-Account {} added").format(acc.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("compensation:acc:detail", id=acc.id)
        else:
            messages.error(request, FORM_INVALID, extra_tags="danger", )

        context = {
            "form": data_form,
            "geom_form": geom_form,
            TAB_TITLE_IDENTIFIER: _("New Eco-Account"),
        }
        context = BaseContext(request, context).context

        return render(request, self._TEMPLATE, context)

class EcoAccountIdentifierGeneratorView(AbstractIdentifierGeneratorView):
    _MODEL = EcoAccount


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

    @method_decorator(default_group_required)
    @method_decorator(shared_access_required(EcoAccount, "id"))
    def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse:

        """
        Renders a view for editing compensations

        Args:
            request (HttpRequest): The incoming request

        Returns:

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

        # Create forms, initialize with values from db/from POST request
        data_form = EditEcoAccountForm(request.POST or None, instance=acc)
        geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=acc)

        context = {
            "form": data_form,
            "geom_form": geom_form,
            TAB_TITLE_IDENTIFIER: _("Edit {}").format(acc.identifier),
        }
        context = BaseContext(request, context).context
        return render(request, self._TEMPLATE, context)

    @method_decorator(default_group_required)
    @method_decorator(shared_access_required(EcoAccount, "id"))
    def post(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse:

        """
        Renders a view for editing compensations

        Args:
            request (HttpRequest): The incoming request

        Returns:

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

        # Create forms, initialize with values from db/from POST request
        data_form = EditEcoAccountForm(request.POST or None, instance=acc)
        geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=acc)

        data_form_valid = data_form.is_valid()
        geom_form_valid = geom_form.is_valid()
        if data_form_valid and geom_form_valid:
            # The data form takes the geom form for processing, as well as the performing user
            acc = data_form.save(request.user, geom_form)
            messages.success(request, _("Eco-Account {} edited").format(acc.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("compensation:acc:detail", id=acc.id)
        else:
            messages.error(request, FORM_INVALID, extra_tags="danger", )

        context = {
            "form": data_form,
            "geom_form": geom_form,
            TAB_TITLE_IDENTIFIER: _("Edit {}").format(acc.identifier),
        }
        context = BaseContext(request, context).context

        return render(request, self._TEMPLATE, context)
