from django.apps import apps

from ocyan.core.utils import find_first, merge_dicts

from ocyan.plugin.oscar.settings import (
    OSCAR_DJANGO_CONFIGURATION,
    OSCAR_OCYAN_CONFIGURATION,
    OXYAN_TEMPLATE_SETTINGS,
)
from ocyan.plugin.oscar.shared.entrypoint import SharedOscarEntrypoint


class OscarConfig(SharedOscarEntrypoint):
    def contribute_to_settings(self, settings):
        # We definately don't want promotions in oscar 3
        OSCAR_OCYAN_CONFIGURATION["OSCAR_PROMOTIONS_ENABLED"] = False
        settings = merge_dicts(settings, OSCAR_OCYAN_CONFIGURATION)

        # find django template settings dict
        django_templates = find_first(
            lambda x: x["BACKEND"].endswith("DjangoTemplates"), settings["TEMPLATES"]
        )

        # configure templates
        merge_dicts(django_templates, OXYAN_TEMPLATE_SETTINGS, overwrite=True)

        # configure auth backends and haystack
        return merge_dicts(settings, OSCAR_DJANGO_CONFIGURATION)

    def contribute_to_fixtures(self, fixtures):
        fixtures = super().contribute_to_fixtures(fixtures)
        fixtures.add("catalogue", "oscar_demo_data/catalogue")
        return fixtures

    def contribute_to_installed_apps(self, installed_apps):
        installed_apps.django.extend(
            ("django.contrib.sites", "django.contrib.flatpages")
        )
        installed_apps.apps.extend(
            (
                "widget_tweaks",
                "haystack",
                "treebeard",
                "sorl.thumbnail",
                "django_tables2",
            )
        )

        installed_apps.ocyan.append("ocyan.plugin.oscar.taxes")
        installed_apps.oscar.extend(
            [
                "ocyan.plugin.oscar.config.OcyanPluginOscarConfig",
                "oscar.apps.analytics.apps.AnalyticsConfig",
                "oscar.apps.checkout.apps.CheckoutConfig",
                "oscar.apps.address.apps.AddressConfig",
                "oscar.apps.shipping.apps.ShippingConfig",
                "oscar.apps.catalogue.apps.CatalogueConfig",
                "oscar.apps.catalogue.reviews.apps.CatalogueReviewsConfig",
                "oscar.apps.communication.apps.CommunicationConfig",
                "oscar.apps.partner.apps.PartnerConfig",
                "oscar.apps.basket.apps.BasketConfig",
                "oscar.apps.payment.apps.PaymentConfig",
                "oscar.apps.offer.apps.OfferConfig",
                "oscar.apps.order.apps.OrderConfig",
                "oscar.apps.customer.apps.CustomerConfig",
                "oscar.apps.search.apps.SearchConfig",
                "oscar.apps.voucher.apps.VoucherConfig",
                "oscar.apps.wishlists.apps.WishlistsConfig",
                "oscar.apps.dashboard.apps.DashboardConfig",
                "oscar.apps.dashboard.reports.apps.ReportsDashboardConfig",
                "oscar.apps.dashboard.users.apps.UsersDashboardConfig",
                "oscar.apps.dashboard.orders.apps.OrdersDashboardConfig",
                "oscar.apps.dashboard.catalogue.apps.CatalogueDashboardConfig",
                "oscar.apps.dashboard.offers.apps.OffersDashboardConfig",
                "oscar.apps.dashboard.partners.apps.PartnersDashboardConfig",
                "oscar.apps.dashboard.pages.apps.PagesDashboardConfig",
                "oscar.apps.dashboard.ranges.apps.RangesDashboardConfig",
                "oscar.apps.dashboard.reviews.apps.ReviewsDashboardConfig",
                "oscar.apps.dashboard.vouchers.apps.VouchersDashboardConfig",
                "oscar.apps.dashboard.communications.apps.CommunicationsDashboardConfig",
                "oscar.apps.dashboard.shipping.apps.ShippingDashboardConfig",
                "ocyan.plugin.oscar.apps.Shop",
            ]
        )

        # register an extesion for oscar, to override oscar base templates
        # the templates in this extension will override oscar templates, but
        # can still be extended in plugins and ocyan.themes
        installed_apps.oscar.register_extension(
            "ocyan.plugin.oscar.oscar_extension", "oscar"
        )

        installed_apps.oscar.register_extension(
            "ocyan.plugin.oscar.oxyan_oscar_extension",
            "ocyan.plugin.oscar.oscar_extension",
        )

        installed_apps.oscar.register_extension(
            "ocyan.plugin.oscar.dashboard",
            "oscar.apps.dashboard",
        )

        return installed_apps

    def contribute_to_i18n_fields(self, fields_dict):
        fields_dict = super().contribute_to_i18n_fields(fields_dict)
        fields_dict.update(
            {
                "communication.communicationeventtype.email_subject_template": True,
                "communication.communicationeventtype.email_body_template": True,
                "communication.communicationeventtype.email_body_html_template": True,
                "communication.communicationeventtype.sms_template": True,
            }
        )
        return fields_dict

    def get_app_config(self):
        return apps.get_app_config("oscar")

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