from __future__ import absolute_import, unicode_literals

import json

from django import forms, VERSION
from django.contrib.admin.checks import InlineModelAdminChecks, ModelAdminChecks
from django.contrib.admin.options import ModelAdmin, StackedInline
from django.contrib.admin.utils import flatten_fieldsets
from django.core import checks
from django.utils.encoding import force_text
from django.utils.text import capfirst
from django.utils.translation import ugettext

from js_asset.js import JS


__all__ = ("ContentEditorInline", "ContentEditor")


class ContentEditorChecks(ModelAdminChecks):
    def check(self, admin_obj, **kwargs):
        errors = super(ContentEditorChecks, self).check(admin_obj, **kwargs)
        errors.extend(self.check_content_editor_regions_attribute(admin_obj))
        return errors

    def check_content_editor_regions_attribute(self, admin_obj):
        if not getattr(admin_obj.model, "regions", False):
            return [
                checks.Error(
                    "ContentEditor models require a non-empty 'regions'"
                    " attribute or property.",
                    obj=admin_obj.__class__,
                    id="content_editor.E002",
                )
            ]

        return []


class ContentEditorInlineChecks(InlineModelAdminChecks):
    def check(self, inline_obj, **kwargs):
        errors = super(ContentEditorInlineChecks, self).check(inline_obj, **kwargs)
        errors.extend(self.check_content_editor_fields_in_fieldset(inline_obj))
        return errors

    def check_content_editor_fields_in_fieldset(self, obj):
        if obj.fieldsets is None:
            return []

        fields = flatten_fieldsets(obj.fieldsets)
        if all(field in fields for field in ("region", "ordering")):
            return []

        return [
            checks.Error(
                "fieldsets must contain both 'region' and 'ordering'.",
                obj=obj.__class__,
                id="content_editor.E001",
            )
        ]


class ContentEditorInline(StackedInline):
    """
    Custom ``admin.StackedInline`` subclass used for content types.

    This inline has to be used for content editor inlines, because the content
    editor uses the type to differentiate between plugins and other inlines.
    """

    extra = 0
    fk_name = "parent"
    regions = None
    if VERSION > (1, 9):  # pragma: no cover
        checks_class = ContentEditorInlineChecks

    def formfield_for_dbfield(self, db_field, *args, **kwargs):
        """Ensure ``region`` and ``ordering`` use a HiddenInput widget"""
        # `request` was made a positional argument in dbb0df2a0 (2015-12-24)
        if db_field.name in ("region", "ordering"):
            kwargs["widget"] = forms.HiddenInput
        return super(ContentEditorInline, self).formfield_for_dbfield(
            db_field, *args, **kwargs
        )

    @classmethod
    def create(cls, model, **kwargs):
        """Create a inline for the given model

        Usage::

            ContentEditorInline.create(MyPlugin, form=MyPluginForm, ...)
        """
        kwargs["model"] = model
        return type(
            str(
                "ContentEditorInline_%s_%s"
                % (model._meta.app_label, model._meta.model_name)
            ),
            (cls,),
            kwargs,
        )


class ContentEditor(ModelAdmin):
    """
    The ``ContentEditor`` is a drop-in replacement for ``ModelAdmin`` with the
    speciality of knowing how to work with content editor plugins (that is,
    :class:`content_editor.admin.ContentEditorInline` inlines).

    It does not have any public API except from everything inherited from
    the standard ``ModelAdmin`` class.
    """

    if VERSION > (1, 9):  # pragma: no cover
        checks_class = ContentEditorChecks

    def _content_editor_context(self, request, context):
        instance = context.get("original")
        if not instance:
            instance = self.model()

        plugins = []
        for iaf in context.get("inline_admin_formsets", []):
            if not isinstance(iaf.opts, ContentEditorInline):
                continue
            regions = (
                iaf.opts.regions({region.key for region in instance.regions})
                if callable(iaf.opts.regions)
                else iaf.opts.regions
            )
            meta = iaf.opts.model._meta
            plugins.append(
                {
                    "key": "{}_{}".format(meta.app_label, meta.model_name),
                    "title": capfirst(force_text(meta.verbose_name)),
                    "regions": list(regions) if regions else None,
                    "prefix": iaf.formset.prefix,
                }
            )
        regions = [
            {
                "key": region.key,
                "title": force_text(region.title),
                "inherited": region.inherited,
                # TODO correct template when POSTing?
            }
            for region in instance.regions
        ]

        return json.dumps(
            {
                "plugins": plugins,
                "regions": regions,
                "messages": {
                    "createNew": ugettext("Add new item"),
                    "empty": ugettext("No items."),
                    "emptyInherited": ugettext("No items. Region may inherit content."),
                    "toggle": ugettext("Show/hide contents"),
                },
            }
        )

    def _content_editor_media(self, request, context):
        return forms.Media(
            css={"all": ["content_editor/content_editor.css"]},
            js=[
                "admin/js/jquery.init.js",
                "content_editor/tabbed_fieldsets.js",
                JS(
                    "content_editor/content_editor.js",
                    {
                        "id": "content-editor-context",
                        "data-context": self._content_editor_context(request, context),
                    },
                ),
            ],
        )

    def render_change_form(self, request, context, **kwargs):
        response = super(ContentEditor, self).render_change_form(
            request, context, **kwargs
        )

        response.context_data["media"] = response.context_data[
            "media"
        ] + self._content_editor_media(request, response.context_data)

        return response

@@ -455,17 +455,16 @@
  import 
-u
 gettext%0A
@@ -5186,17 +5186,16 @@
 teNew%22: 
-u
 gettext(
@@ -5240,17 +5240,16 @@
 empty%22: 
-u
 gettext(
@@ -5300,17 +5300,16 @@
 rited%22: 
-u
 gettext(
@@ -5380,17 +5380,16 @@
 oggle%22: 
-u
 gettext(

Replace ugettext with gettext