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

"""
from user.models import User
from django.db import transaction
from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext_lazy as _

from compensation.forms.mixins import CompensationResponsibleFormMixin, PikCompensationFormMixin
from compensation.forms.compensation import AbstractCompensationForm
from ema.models import Ema, EmaDocument
from intervention.models import Responsibility, Handler
from konova.forms import SimpleGeomForm
from konova.forms.modals import NewDocumentModalForm
from user.models import UserActionLogEntry


class NewEmaForm(AbstractCompensationForm, CompensationResponsibleFormMixin, PikCompensationFormMixin):
    """ Form for creating new EMA objects.

    Inherits basic form fields from AbstractCompensationForm and additional from CompensationResponsibleFormMixin.
    Second holds self.instance.response related fields

    """
    field_order = [
        "identifier",
        "title",
        "conservation_office",
        "conservation_file_number",
        "is_pik",
        "handler_type",
        "handler_detail",
        "comment",
    ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.form_title = _("New EMA")

        self.action_url = reverse("ema:new")
        self.cancel_redirect = reverse("ema:index")

        tmp = Ema()
        identifier = tmp.generate_new_identifier()
        self.initialize_form_field("identifier", identifier)
        self.fields["identifier"].widget.attrs["url"] = reverse_lazy("ema:new-id")
        self.fields["title"].widget.attrs["placeholder"] = _("Compensation XY; Location ABC")

    def save(self, user: User, geom_form: SimpleGeomForm):
        with transaction.atomic():
            # Fetch data from cleaned POST values
            identifier = self.cleaned_data.get("identifier", None)
            title = self.cleaned_data.get("title", None)
            handler_type = self.cleaned_data.get("handler_type", None)
            handler_detail = self.cleaned_data.get("handler_detail", None)
            conservation_office = self.cleaned_data.get("conservation_office", None)
            conservation_file_number = self.cleaned_data.get("conservation_file_number", None)
            is_pik = self.cleaned_data.get("is_pik", None)
            comment = self.cleaned_data.get("comment", None)

            # Create log entry
            action = UserActionLogEntry.get_created_action(user)

            handler = Handler.objects.create(
                type=handler_type,
                detail=handler_detail
            )
            responsible = Responsibility.objects.create(
                handler=handler,
                conservation_file_number=conservation_file_number,
                conservation_office=conservation_office,
            )

            # Finally create main object
            ema = Ema.objects.create(
                identifier=identifier,
                title=title,
                responsible=responsible,
                created=action,
                modified=action,
                comment=comment,
                is_pik=is_pik,
            )

            # Add the creating user to the list of shared users
            ema.share_with_user(user)

            # Add the log entry to the main objects log list
            ema.log.add(action)

        # Process the geometry form (NOT ATOMIC TRANSACTION DUE TO CELERY!)
        geometry = geom_form.save(action)
        ema.geometry = geometry
        ema.save()
        return ema


class EditEmaForm(NewEmaForm):
    """ Form for editing EMAs

    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.form_title = _("Edit EMA")

        self.action_url = reverse("ema:edit", args=(self.instance.id,))
        self.cancel_redirect = reverse("ema:detail", args=(self.instance.id,))

        self.fields["identifier"].widget.attrs["url"] = reverse_lazy("ema:new-id")
        self.fields["title"].widget.attrs["placeholder"] = _("Compensation XY; Location ABC")

        # Initialize form data
        form_data = {
            "identifier": self.instance.identifier,
            "title": self.instance.title,
            "handler_type": self.instance.responsible.handler.type,
            "handler_detail": self.instance.responsible.handler.detail,
            "conservation_office": self.instance.responsible.conservation_office,
            "conservation_file_number": self.instance.responsible.conservation_file_number,
            "comment": self.instance.comment,
            "is_pik": self.instance.is_pik,
        }
        disabled_fields = []
        self.load_initial_data(
            form_data,
            disabled_fields
        )

    def save(self, user: User, geom_form: SimpleGeomForm):
        with transaction.atomic():
            # Fetch data from cleaned POST values
            title = self.cleaned_data.get("title", None)
            handler_type = self.cleaned_data.get("handler_type", None)
            handler_detail = self.cleaned_data.get("handler_detail", None)
            conservation_office = self.cleaned_data.get("conservation_office", None)
            conservation_file_number = self.cleaned_data.get("conservation_file_number", None)
            comment = self.cleaned_data.get("comment", None)
            is_pik = self.cleaned_data.get("is_pik", None)

            # Create log entry
            action = UserActionLogEntry.get_edited_action(user)

            # Update responsible data
            self.instance.responsible.handler.type = handler_type
            self.instance.responsible.handler.detail = handler_detail
            self.instance.responsible.handler.save()
            self.instance.responsible.conservation_office = conservation_office
            self.instance.responsible.conservation_file_number = conservation_file_number
            self.instance.responsible.save()

            # Update main oject data
            self.instance.title = title
            self.instance.comment = comment
            self.instance.is_pik = is_pik
            self.instance.modified = action
            self.instance.save()

            # Add the log entry to the main objects log list
            self.instance.log.add(action)

        # Process the geometry form (NOT ATOMIC TRANSACTION DUE TO CELERY!)
        geometry = geom_form.save(action)
        self.instance.geometry = geometry
        self.instance.save()
        return self.instance


class NewEmaDocumentModalForm(NewDocumentModalForm):
    document_model = EmaDocument