from django.urls import path, reverse_lazy
from django.views.decorators.cache import cache_page

from ocyan.core.utils import merge_dicts
from ocyan.plugin.wagtail.block_plugin import BlockPluginConfig

from .constants import CACHE_DURATION

WOI_SETTINGS = {
    "STATICFILES_FINDERS": [
        "ocyan.plugin.wagtail_oscar_integration.utils.StaticSrcFinder"
    ],
    "WAGTAIL_FRONTEND_LOGIN_URL": reverse_lazy("customer:login"),
}


class WagtailOscarIntegrationConfig(BlockPluginConfig):
    def contribute_to_settings(self, settings):
        return merge_dicts(settings, WOI_SETTINGS)

    def get_smoketest_modules(self):
        return ["ocyan.plugin.wagtail_oscar_integration.tests.test_smoketests"]

    def contribute_to_installed_apps(self, installed_apps):
        installed_apps.django.append("django.contrib.sitemaps")
        installed_apps.ocyan.append("ocyan.plugin.wagtail_oscar_integration")
        installed_apps.wagtail.extend(
            [
                "wagtail.contrib.settings",
                "ocyan.plugin.wagtail_oscar_integration.wagtail_extension",
            ]
        )
        installed_apps.wagtail.register_extension(
            "ocyan.plugin.wagtail_oscar_integration.wagtail_oscar_integration_coyote_extension",
            "ocyan.plugin.coyote",
        )

        installed_apps.wagtail.append(
            "ocyan.plugin.wagtail_oscar_integration.wagtail_user_extension.apps.CustomUsersAppConfig",
            replaces="wagtail.users",
        )
        return installed_apps

    def contribute_to_middleware(self, middleware):
        return middleware + [
            "ocyan.plugin.wagtail_oscar_integration.middleware.oscar_dashboard_2_wagtail"
        ]

    def contribute_to_urlpatterns(self, urlpatterns):
        from django.contrib.sitemaps import views

        from ocyan.main.loading import get_ocyan_class

        gather_sitemaps = get_ocyan_class(
            "wagtail_oscar_integration.sitemap", "gather_sitemaps"
        )

        sitemaps = gather_sitemaps()

        return [
            path(
                "sitemap.xml",
                cache_page(CACHE_DURATION)(views.index),
                {"sitemaps": sitemaps, "sitemap_url_name": "sitemaps"},
            ),
            path(
                "sitemap-<section>.xml",
                cache_page(CACHE_DURATION)(views.sitemap),
                {"sitemaps": sitemaps},
                name="sitemaps",
            ),
        ] + urlpatterns

    def get_spooler_modules(self, modules):
        modules.append("ocyan.plugin.wagtail_oscar_integration.spooler")
        return modules

    def contribute_to_blocks(self, blocks):
        from .blocks import (
            CategoryCCHooserBlock,
            ProductChooserBlock,
            ProductSliderBlock,
            RecentlyViewedBlock,
        )
        from .category_block import CategoryChooserBlock

        return blocks + [
            ("Category", CategoryChooserBlock()),
            ("CategoryCBlock", CategoryCCHooserBlock(), "roadrunner"),
            ("Recent", RecentlyViewedBlock(), "roadrunner,rr"),
            ("ProductSlider", ProductSliderBlock()),
            (
                "add_to_cart",
                ProductChooserBlock(
                    template="wagtail_content_page/partials/add-to-cart.html"
                ),
                "contentpage",
            ),
        ]

    def contribute_to_maintenance(self, maintenances):
        return maintenances + [
            (
                "helpdesk_group",
                "ocyan.plugin.wagtail_oscar_integration.maintenance.helpdesk_group",
            ),
        ]


class WagtailOscar3IntegrationConfig(WagtailOscarIntegrationConfig):
    def contribute_to_middleware(self, middleware):
        return middleware

    def contribute_to_installed_apps(self, installed_apps):
        installed_apps = super().contribute_to_installed_apps(installed_apps)
        installed_apps.ocyan.register_extension(
            "ocyan.plugin.wagtail_oscar_integration.oxyan_wagtail_oscar_integration",
            "ocyan.plugin.wagtail_oscar_integration",
        )
        return installed_apps
