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

"""
from dal import autocomplete
from django import forms
from django.contrib.auth.models import User
from django.contrib.gis import forms as gis_forms
from django.contrib.gis.geos import Polygon
from django.db import transaction
from django.urls import reverse
from django.utils.translation import gettext_lazy as _

from intervention.models import Intervention
from konova.forms import BaseForm
from konova.models import Document
from konova.settings import DEFAULT_LAT, DEFAULT_LON, DEFAULT_ZOOM
from organisation.models import Organisation


class NewInterventionForm(BaseForm):
    identifier = forms.CharField(
        label=_("Identifier"),
        label_suffix="",
        max_length=255,
        help_text=_("Generated automatically if none was given"),
        required=False,
    )
    title = forms.CharField(
        label=_("Title"),
        label_suffix="",
        max_length=255,
    )
    type = forms.CharField(
        label=_("Type"),
        label_suffix="",
        max_length=255,
        help_text=_("Which intervention type is this"),
    )
    law = forms.CharField(
        label=_("Law"),
        label_suffix="",
        max_length=255,
        help_text=_("Based on which law"),
    )
    handler = forms.CharField(
        label=_("Intervention handler"),
        label_suffix="",
        max_length=255,
        help_text=_("Who performs the intervention"),
    )
    data_provider = forms.ModelChoiceField(
        label=_("Data provider"),
        label_suffix="",
        help_text=_("Who provides the data for the intervention"),
        queryset=Organisation.objects.all(),
        widget=autocomplete.ModelSelect2(
            url="other-orgs-autocomplete",
            attrs={
                "data-placeholder": _("Organization"),
                "data-minimum-input-length": 3,
            }
        ),
    )
    data_provider_detail = forms.CharField(
        label=_("Data provider details"),
        label_suffix="",
        max_length=255,
        help_text=_("Further details"),
        required=False,
    )
    geometry = gis_forms.MultiPolygonField(
        widget=gis_forms.OSMWidget(
            attrs={
                "default_lat": DEFAULT_LAT,
                "default_lon": DEFAULT_LON,
                "default_zoom": DEFAULT_ZOOM,
                'map_width': 800,
                'map_height': 500
            },
        ),
        label=_("Map"),
        label_suffix="",
        help_text=_("Where does the intervention take place")
    )
    documents = forms.FileField(
        widget=forms.ClearableFileInput(
            attrs={
                "multiple": True,
            }
        ),
        label=_("Files"),
        label_suffix="",
        required=False,
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.form_title = _("New intervention")
        self.action_url = reverse("intervention:new")
        self.cancel_redirect = reverse("intervention:index")

    def save(self, user: User):
        with transaction.atomic():
            identifier = self.cleaned_data.get("identifier", None)
            title = self.cleaned_data.get("title", None)
            _type = self.cleaned_data.get("type", None)
            law = self.cleaned_data.get("law", None)
            handler = self.cleaned_data.get("handler", None)
            data_provider = self.cleaned_data.get("data_provider", None)
            data_provider_detail = self.cleaned_data.get("data_provider_detail", None)
            geometry = self.cleaned_data.get("geometry", Polygon())
            documents = self.cleaned_data.get("documents", []) or []

            intervention = Intervention(
                identifier=identifier,
                title=title,
                type=_type,
                law=law,
                handler=handler,
                data_provider=data_provider,
                data_provider_detail=data_provider_detail,
                geometry=geometry,
                created_by=user,
            )
            intervention.save()
            for doc in documents:
                doc_obj = Document()
                doc_obj.document = doc
                # ToDo Add functionality for other attributes
                doc_obj.save()
                intervention.documents.add(doc_obj)
        return intervention


class EditInterventionForm(NewInterventionForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance is not None:
            self.action_url = reverse("intervention:edit", args=(self.instance.id,))
        self.cancel_redirect = reverse("intervention:index")
        self.form_title = _("Edit intervention")
        self.form_caption = ""

        # Initialize form data
        form_data = {
            "identifier": self.instance.identifier,
            "title": self.instance.title,
            "type": self.instance.type,
            "law": self.instance.law,
            "handler": self.instance.handler,
            "data_provider": self.instance.data_provider,
            "data_provider_detail": self.instance.data_provider_detail,
            "geometry": self.instance.geometry,
            "documents": self.instance.documents.all(),
        }
        disabled_fields = [
            "identifier",
        ]
        self.load_initial_data(
            form_data,
            disabled_fields,
        )

    def save(self, user: User):
        """ Overwrite instance with new form data

        Args:
            user ():

        Returns:

        """
        with transaction.atomic():
            identifier = self.cleaned_data.get("identifier", None)
            title = self.cleaned_data.get("title", None)
            _type = self.cleaned_data.get("type", None)
            law = self.cleaned_data.get("law", None)
            handler = self.cleaned_data.get("handler", None)
            data_provider = self.cleaned_data.get("data_provider", None)
            data_provider_detail = self.cleaned_data.get("data_provider_detail", None)
            geometry = self.cleaned_data.get("geometry", Polygon())
            documents = self.cleaned_data.get("documents", []) or []

            self.instance.identifier = identifier
            self.instance.title = title
            self.instance.type = _type
            self.instance.law = law
            self.instance.handler = handler
            self.instance.data_provider = data_provider
            self.instance.data_provider_detail = data_provider_detail
            self.instance.geometry = geometry
            self.instance.save()

            for doc in documents:
                doc_obj = Document()
                doc_obj.document = doc
                # ToDo Add functionality for other attributes
                doc_obj.save()
                self.instance.documents.add(doc_obj)
        return self.instance


class OpenInterventionForm(EditInterventionForm):
    """
    This form is not intended to be used as data-input form. It's used to simplify the rendering of intervention:open
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Resize map
        self.fields["geometry"].widget.attrs["map_width"] = 500
        self.fields["geometry"].widget.attrs["map_height"] = 300

        # Disable all form fields
        for field in self.fields:
            self.disable_form_field(field)