# -*- coding: utf-8 -*-
import logging

from django.apps import apps
from django.conf.urls.i18n import i18n_patterns
from django.urls import include, path

from ocyan.core.fender import config
from ocyan.core.plugins import OcyanPluginConfig
from ocyan.core.utils import merge_dicts
from ocyan.plugin.oscar.pipeline import PIPELINE_STATUS_COMPLETE
from ocyan.plugin.oscar.settings import OSCAR_ORDER_STATUS_CASCADE

logger = logging.getLogger(__name__)


class OscarCommunicationsConfig(OcyanPluginConfig):
    def contribute_to_installed_apps(self, installed_apps):
        installed_apps.django.append("sequences.apps.SequencesConfig")
        installed_apps.ocyan.append("oscar_invoices")
        installed_apps.ocyan.append("ocyan.plugin.oscar_communications")
        installed_apps.ocyan.append(
            "ocyan.plugin.oscar_communications.oscar_invoices_extension",
            extends="oscar_invoices",
        )

        installed_apps.oscar.append(
            "ocyan.plugin.oscar_communications.customer_extension",
            extends="oscar.apps.customer",
        )
        installed_apps.oscar.register_extension(
            "ocyan.plugin.oscar_communications.customer_extension",
            "ocyan.plugin.oscar_multi_site.customer_alerts_ms_extension",
        )
        installed_apps.oscar.register_extension(
            "ocyan.plugin.oscar_communications.order_extension",
            "ocyan.plugin.oscar_order.order",
        )
        return installed_apps

    def contribute_to_settings(self, settings):
        # we will remove the cascading of PIPELINE_STATUS_COMPLETE from the
        # order to the lines, because it will be handled by shipping events in
        # this plugin
        try:
            # modify the setting by it's reference directly
            del OSCAR_ORDER_STATUS_CASCADE[PIPELINE_STATUS_COMPLETE]
        except KeyError:
            pass

        return settings

    def _get_invoice_url_target(self):
        invoice_app = apps.get_app_config("oscar_invoices")
        invoice_urls = getattr(invoice_app, "urls", None)
        if invoice_urls is not None:
            return invoice_urls

        get_urls = getattr(invoice_app, "get_urls", None)
        if callable(get_urls):
            namespace = getattr(invoice_app, "namespace", invoice_app.label)
            return include((get_urls(), invoice_app.label), namespace=namespace)

        raise AttributeError(
            "oscar_invoices app config does not expose urls/get_urls"
        )

    def contribute_to_urlpatterns(self, urlpatterns):
        new_patterns = []
        try:
            new_patterns.append(
                path(r"dashboard/oscar-invoices/", self._get_invoice_url_target())
            )
        except (LookupError, AttributeError) as exc:
            logger.warning("Skipping oscar_invoices dashboard urls: %s", exc)
        if config.i18n_enabled:
            new_patterns += i18n_patterns(
                path(
                    r"admin/communications/",
                    include("ocyan.plugin.oscar_communications.urls"),
                ),
                prefix_default_language=False,
            )
        else:
            new_patterns.append(
                path(
                    r"admin/communications/",
                    include("ocyan.plugin.oscar_communications.urls"),
                )
            )

        new_patterns.extend(list(urlpatterns))
        return new_patterns

    def contribute_to_fixtures(self, fixtures):
        fixtures.add("invoices", "communications_demo_data/invoices")
        return fixtures

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


class Oscar3CommunicationsConfig(OscarCommunicationsConfig):
    def contribute_to_installed_apps(self, installed_apps):
        installed_apps = super().contribute_to_installed_apps(installed_apps)
        installed_apps.oscar.append(
            "ocyan.plugin.oscar_communications.communication.apps.CommunicationConfig",
            replaces="oscar.apps.communication.apps.CommunicationConfig",
        )
        installed_apps.oscar.register_extension(
            "ocyan.plugin.oscar_communications.customer_extension",
            "oscar.apps.communication",
        )
        installed_apps.oscar.register_extension(
            "ocyan.plugin.oscar_communications.oxyan_communications_extension",
            "ocyan.plugin.oscar_communications.customer_extension",
        )
        return installed_apps

    def contribute_to_settings(self, settings):
        return merge_dicts(
            settings,
            {
                "MIGRATION_MODULES": {
                    "communication": "ocyan.plugin.oscar_communications.communication.migrations"
                },
            },
        )
