from wagtail import blocks

from oscar.core.loading import get_model

from ocyan.main.loading import get_ocyan_classes

from .viewsets import category_chooser_viewset, product_chooser_viewset

# we need a double fallback for BaseStylingBlock until we finished the
# transition to wagtail-roadrunner completely
try:
    from rr.blocks.styling import StylingBlock as BaseStylingBlock
except ImportError:
    try:
        from roadrunner.blocks.styling import BaseStylingBlock
    except ImportError:
        BaseStylingBlock = lambda: blocks.StaticBlock(
            admin_text="Install roadrunner_bs4 or roadrunner_bs5",
            template="roadrunner/stylingblockplaceholder.html",
        )

# pylint: disable=unbalanced-tuple-unpacking
AdminCategoryChooser, AdminProductChooser = get_ocyan_classes(
    "wagtail_oscar_integration.widgets", ["AdminCategoryChooser", "AdminProductChooser"]
)

Product = get_model("catalogue", "Product")


ProductChooserBlock = product_chooser_viewset.get_block_class(
    name="ProductChooserBlock",
    module_path="ocyan.plugin.wagtail_oscar_integration.blocks",
)

CategoryChooserBlock = category_chooser_viewset.get_block_class(
    name="CategoryChooserBlock",
    module_path="ocyan.plugin.wagtail_oscar_integration.blocks",
)


class ProductBlock(blocks.StructBlock):
    product = ProductChooserBlock()

    class Meta:
        icon = "arrow-right"
        label = "product"
        group = "Webshop"
        preview = ["product"]


def ProductSliderBlock(**kwargs):
    kwargs.setdefault("template", "roadrunner_bs4/blocks/product_slider.html")
    kwargs.setdefault("icon", "code")
    kwargs.setdefault("label", "products")
    kwargs.setdefault("group", "Webshop")
    return blocks.ListBlock(ProductBlock(), **kwargs)


class RoadrunnerCategoryChooserBlock(CategoryChooserBlock):
    add_choices_to_source = True


class CategoryCCHooserBlock(blocks.StructBlock):
    category = RoadrunnerCategoryChooserBlock(required=False)
    label = blocks.CharBlock(label="Alternative label", required=False)
    styling = BaseStylingBlock()

    def get_context(self, value, parent_context=None):
        context = super().get_context(value, parent_context=parent_context)
        if value["category"]:
            products = (
                Product.objects.browsable()
                .filter(categories__in=[value["category"]])
                .distinct()
                .order_by("-priority", "title")
            )
            context["products"] = products
        else:
            context["products"] = Product.objects.none()
            warning = f"CategoryChooserBlock name={self.name}, definition_prefix={self.definition_prefix} is missing the category"
            page = parent_context.get("page", None)
            if page is not None:
                warning += f" on page {page} (pk={page.pk})"
        return context

    class Meta:
        template = "roadrunner_bs4/blocks/category_c_block.html"
        icon = "link"
        label = "Category 2"
        group = "Webshop"


class RecentlyViewedBlock(blocks.StructBlock):
    styling = BaseStylingBlock()

    class Meta:
        template = "roadrunner_bs4/blocks/recently_viewed_block.html"
        icon = "view"
        label = "Recent Bekeken"
        group = "Webshop"
