# django.views.generic.edit.UpdateView
from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.http import HttpResponseRedirect
from django.urls import path, reverse_lazy
from django.utils.text import camel_case_to_spaces
from django.utils.translation import gettext_lazy as _
from django.views.generic import UpdateView

from wagtail.admin.viewsets.base import ViewSet

from .forms import mappingmodelformset_factory
from .models import MappingModel


class MappingView(UpdateView):
    template_name = "wagtailadmin/mapping/edit.html"
    model = MappingModel
    associated_model = None
    mapping_class = None
    menu_label = None
    help_text = None

    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        # pylint: disable=protected-access
        ctx["standard_mapping"] = [
            x for x in self.mapping_class._mapping_rules if x.from_field
        ]
        return ctx

    def get_object(self, queryset=None):
        c_type = ContentType.objects.get_for_model(self.associated_model)
        obj, _ = MappingModel.objects.get_or_create(contenttype=c_type)
        return obj

    def get_queryset(self):
        c_type = ContentType.objects.get_for_model(self.associated_model)
        return super().get_queryset().filter(contenttype=c_type)

    def form_valid(self, form):
        form.save()
        messages.info(self.request, _("Your mapping was successfully saved!"))
        return HttpResponseRedirect(self.get_success_url())


class MappingEditorViewSet(ViewSet):
    menu_label = None
    icon = "resubmit"
    mapping_class = None
    associated_model = None
    help_text = None

    def __init__(self, name=None, **kwargs):
        super().__init__(name, **kwargs)
        if self.mapping_class is None:
            raise ValidationError("MappingEditorViewSet created without mapping_class")
        if self.associated_model is None:
            raise ValidationError(
                "MappingEditorViewSet created without associated_model"
            )
        if self.menu_label is None:
            self.menu_label = camel_case_to_spaces(
                self.mapping_class.__name__
            ).capitalize()

        if self.name is None:
            self.name = self.mapping_class.__name__.lower()

    def get_urlpatterns(self):
        return [
            path(
                "",
                MappingView.as_view(
                    mapping_class=self.mapping_class,
                    associated_model=self.associated_model,
                    form_class=mappingmodelformset_factory(self.mapping_class),
                    success_url=reverse_lazy("%s:index" % self.name),
                    menu_label=self.menu_label,
                    help_text=self.help_text,
                ),
                name="index",
            )
        ]
