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

"""
from django import forms
from django.db import transaction
from django.db.models.fields.files import FieldFile
from django.utils.translation import gettext_lazy as _

from konova.forms.modals.base_form import BaseModalForm
from konova.models import AbstractDocument
from konova.utils import validators
from konova.utils.message_templates import DOCUMENT_EDITED, FILE_SIZE_TOO_LARGE, FILE_TYPE_UNSUPPORTED
from user.models import UserActionLogEntry


class NewDocumentModalForm(BaseModalForm):
    """ Modal form for new documents

    """
    title = forms.CharField(
        label=_("Title"),
        label_suffix=_(""),
        max_length=500,
        widget=forms.TextInput(
            attrs={
                "class": "form-control",
            }
        )
    )
    creation_date = forms.DateField(
        label=_("Created on"),
        label_suffix=_(""),
        help_text=_("When has this file been created? Important for photos."),
        validators=[validators.reasonable_date],
        widget=forms.DateInput(
            attrs={
                "type": "date",
                "data-provide": "datepicker",
                "class": "form-control",
            },
            format="%d.%m.%Y"
        )
    )
    file = forms.FileField(
        label=_("File"),
        label_suffix=_(""),
        help_text=_("Allowed formats: pdf, jpg, png. Max size 15 MB."),
        widget=forms.FileInput(
            attrs={
                "class": "form-control-file",
            }
        ),
    )
    comment = forms.CharField(
        required=False,
        max_length=200,
        label=_("Comment"),
        label_suffix=_(""),
        help_text=_("Additional comment, maximum {} letters").format(200),
        widget=forms.Textarea(
            attrs={
                "cols": 30,
                "rows": 5,
                "class": "form-control",
            }
        )
    )
    document_model = None

    class Meta:
        abstract = True

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.form_title = _("Add new document")
        self.form_caption = _("")
        self.form_attrs = {
            "enctype": "multipart/form-data",  # important for file upload
        }
        if not self.document_model:
            raise NotImplementedError("Unsupported document type for {}".format(self.instance.__class__))

    def is_valid(self):
        super_valid = super().is_valid()

        _file = self.cleaned_data.get("file", None)

        if _file is None or isinstance(_file, FieldFile):
            # FieldFile declares that no new file has been uploaded and we do not need to check on the file again
            return super_valid

        mime_type_valid = self.document_model.is_mime_type_valid(_file)
        if not mime_type_valid:
            self.add_error(
                "file",
                FILE_TYPE_UNSUPPORTED
            )

        file_size_valid = self.document_model.is_file_size_valid(_file)
        if not file_size_valid:
            self.add_error(
                "file",
                FILE_SIZE_TOO_LARGE
            )

        file_valid = mime_type_valid and file_size_valid
        return super_valid and file_valid

    def save(self):
        with transaction.atomic():
            action = UserActionLogEntry.get_created_action(self.user)
            edited_action = UserActionLogEntry.get_edited_action(self.user, _("Added document"))

            doc = self.document_model.objects.create(
                created=action,
                title=self.cleaned_data["title"],
                comment=self.cleaned_data["comment"],
                file=self.cleaned_data["file"],
                date_of_creation=self.cleaned_data["creation_date"],
                instance=self.instance,
            )

            self.instance.log.add(edited_action)
            self.instance.modified = edited_action
            self.instance.save()

            return doc


class EditDocumentModalForm(NewDocumentModalForm):
    document = None
    document_model = AbstractDocument

    def __init__(self, *args, **kwargs):
        self.document = kwargs.pop("document", None)
        super().__init__(*args, **kwargs)
        self.form_title = _("Edit document")
        form_data = {
            "title": self.document.title,
            "comment": self.document.comment,
            "creation_date": str(self.document.date_of_creation),
            "file": self.document.file,
        }
        self.load_initial_data(form_data)

    def save(self):
        with transaction.atomic():
            document = self.document
            file = self.cleaned_data.get("file", None)

            document.title = self.cleaned_data.get("title", None)
            document.comment = self.cleaned_data.get("comment", None)
            document.date_of_creation = self.cleaned_data.get("creation_date", None)
            if not isinstance(file, FieldFile):
                document.replace_file(file)
            document.save()

            self.instance.mark_as_edited(self.user, self.request, edit_comment=DOCUMENT_EDITED)

            return document

