# -*- coding: utf-8 -*-
# pylint: disable=W0212
import re

from django.template import Context, Template
from django.urls import reverse_lazy
from django.utils.html import format_html
from django.utils.translation import gettext

import wagtail.admin.rich_text.editors.draftail.features as draftail_features
from wagtail import hooks
from wagtail.admin.menu import (
    Menu,
)
from wagtail.admin.menu import (
    MenuItem as MenuItem_,
)
from wagtail.admin.menu import (
    SubmenuMenuItem as SubmenuMenuItem_,
)
from wagtail.admin.staticfiles import versioned_static

from oscar.core.loading import get_class
from oscar.templatetags.dashboard_tags import dashboard_navigation

from ocyan.main.loading import get_ocyan_classes
from ocyan.plugin.oscar.info import OSCAR_NEEDS_OXYAN

from .rich_text import CategoryLinkHandler, ProductLinkHandler
from .rich_text.contentstate import (
    ContentstateCategoryLinkConversionRule,
    ContentstateProductLinkConversionRule,
)
from .rich_text.editor_html import (
    EditorHTMLCategoryLinkConversionRule,
    EditorHTMLProductLinkConversionRule,
)
from .viewsets import category_chooser_viewset, product_chooser_viewset

DashboardPermission = get_class("dashboard.permissions", "DashboardPermission")
# pylint: disable=unbalanced-tuple-unpacking
UserBarEditProductItem, UserBarEditCategoryItem = get_ocyan_classes(
    "wagtail_oscar_integration.userbar",
    ["UserBarEditProductItem", "UserBarEditCategoryItem"],
)


FA_REGEX = re.compile(r"^fa.? fa-(?P<icon>.*)")


class OscarMixin:
    def get_context(self, request):
        context = super().get_context(request)
        context["li_additional_classes"] = " oscar"
        return context


class SubmenuMenuItem(OscarMixin, SubmenuMenuItem_):
    pass


class MenuItem(OscarMixin, MenuItem_):
    def is_active(self, request):
        # A menuitem can lead to a different url than the parent has.
        # Wagtail will take care of activating the parent menu item.
        return request.path == str(self.url)


def from_node(node):
    # Convert an Oscar dashboard menu node to Wagtail menu item
    # Nodes with children become a submenu.
    icon = "arrow-right"
    if node.icon:
        icon_match = FA_REGEX.match(node.icon)
        if icon_match is not None:
            icon = icon_match.group("icon")

    if node.children:
        register_hook_name = f"register_oscar_item_{node.label}"
        menu = Menu(register_hook_name=register_hook_name)
        menu.initial_menu_items = [from_node(child) for child in node.children]
        return SubmenuMenuItem(label=node.label, menu=menu, icon_name=icon)
    else:
        return MenuItem(label=node.label, url=node.url, icon_name=icon)


@hooks.register("construct_main_menu")
def create_oscar_menus(request, menuitems):
    nodes = dashboard_navigation(request.user)
    menuitems.extend(from_node(node) for node in nodes)
    return menuitems


if OSCAR_NEEDS_OXYAN:

    @hooks.register("insert_global_admin_css")
    def global_admin_css():
        """Add /static/css/custom.css to the admin."""
        tpl = Template(
            """{% load compress static %}{% compress css %}<link rel="stylesheet" type="text/x-scss" href="{% static 'oscar/oxyan/dashboard.scss' %}">{% endcompress %}"""
        )
        return tpl.render(Context())

else:

    @hooks.register("insert_global_admin_css")
    def global_admin_css():
        return format_html(
            '<link rel="stylesheet" href="{}">',
            versioned_static(
                "ocyan_plugin_wagtail_oscar_integration/wagtail_oscar_dashboard.css"
            ),
        )


@hooks.register("register_admin_viewset")
def register_viewset():
    return product_chooser_viewset, category_chooser_viewset


@hooks.register("construct_wagtail_userbar")
def add_product_edit_item(request, items, page):  # pylint: disable=unused-argument
    try:
        product_slug = request.resolver_match.kwargs.get("product_slug", None)
        pk = request.resolver_match.kwargs.get("pk", None)
        if pk and product_slug:
            items.append(UserBarEditProductItem(pk))
    except AttributeError:
        pass


@hooks.register("construct_wagtail_userbar")
def add_category_edit_item(request, items, page):  # pylint: disable=unused-argument
    try:
        category_slug = request.resolver_match.kwargs.get("category_slug", None)
        pk = request.resolver_match.kwargs.get("pk", None)
        if pk and category_slug:
            items.append(UserBarEditCategoryItem(pk))
    except AttributeError:
        pass


@hooks.register("after_edit_user")
@hooks.register("after_create_user")
def configure_oscar_permissions(request, user):
    if user.is_superuser or DashboardPermission.has_dashboard_perms(user):
        user.is_staff = True
        user.save()


@hooks.register("register_rich_text_features")
def register_productlink_feature(features):
    features.register_link_type(ProductLinkHandler)

    features.register_editor_plugin(
        "draftail",
        "product-link",
        draftail_features.EntityFeature(
            {
                "type": "PRODUCT",
                "icon": "tag",
                "description": gettext("Product"),
                "chooserUrls": {
                    "productChooser": reverse_lazy("product_chooser:choose")
                },
            },
            js=["wagtailadmin/js/product-chooser-modal.js"],
        ),
    )

    features.register_converter_rule(
        "editorhtml", "product-link", EditorHTMLProductLinkConversionRule
    )
    features.register_converter_rule(
        "contentstate", "product-link", ContentstateProductLinkConversionRule
    )

    features.default_features.append("product-link")


@hooks.register("register_rich_text_features")
def register_categorylink_feature(features):
    features.register_link_type(CategoryLinkHandler)

    features.register_editor_plugin(
        "draftail",
        "category-link",
        draftail_features.EntityFeature(
            {
                "type": "CATEGORY",
                "icon": "tasks",
                "description": gettext("Category"),
                "chooserUrls": {
                    "categoryChooser": reverse_lazy("category_chooser:choose")
                },
            },
            js=["wagtailadmin/js/category-chooser-modal.js"],
        ),
    )

    features.register_converter_rule(
        "editorhtml", "category-link", EditorHTMLCategoryLinkConversionRule
    )
    features.register_converter_rule(
        "contentstate", "category-link", ContentstateCategoryLinkConversionRule
    )

    features.default_features.append("category-link")
