from django.db import models
from django.utils.translation import gettext_lazy
from wagtail.admin.edit_handlers import (
    FieldPanel,
    HelpPanel,
    MultiFieldPanel,
    StreamFieldPanel,
)
from wagtail.contrib.table_block.blocks import TableBlock
from wagtail.core import blocks
from wagtail.core.fields import StreamField
from wagtail.core.models import Page
from wagtail.documents.blocks import DocumentChooserBlock
from wagtail.images.blocks import ImageChooserBlock
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtailmetadata.models import MetadataPageMixin

from tuning import help

RICH_TEXT_FEATURES = [
    "h2",
    "h3",
    "h4",
    "h5",
    "bold",
    "italic",
    "ol",
    "ul",
    "hr",
    "link",
    "document-link",
    "image",
    "superscript",
    "subscript",
    "strikethrough",
    "blockquote",
]


BLACK_ON_WHITE = "black_on_white"
WHITE_ON_BLACK = "white_on_black"
WHITE_ON_BLUE = "white_on_blue"
WHITE_ON_CYAN = "white_on_cyan"
WHITE_ON_VIOLET = "white_on_violet"

COLOR_CHOICES = (
    (BLACK_ON_WHITE, "černá na bílé"),
    (WHITE_ON_BLACK, "bílá na černé"),
    (WHITE_ON_BLUE, "bílá na modré"),
    (WHITE_ON_CYAN, "bílá na tyrkysové"),
    (WHITE_ON_VIOLET, "bílá na fialové"),
)

COLOR_CSS = {
    BLACK_ON_WHITE: "",
    WHITE_ON_BLACK: "text-white bg-black",
    WHITE_ON_BLUE: "text-white bg-blue-300",
    WHITE_ON_CYAN: "text-white bg-cyan-300",
    WHITE_ON_VIOLET: "text-white bg-violet-300",
}


class ColorBlock(blocks.StructBlock):
    """
    Intended as parent class for blocks with color option.
    """

    color = blocks.ChoiceBlock(
        label="barva", choices=COLOR_CHOICES, default=BLACK_ON_WHITE
    )

    def get_context(self, value, parent_context=None):
        context = super().get_context(value, parent_context=parent_context)
        context["css_class"] = COLOR_CSS[value["color"]]
        return context


class ColumnsTextBlock(blocks.StructBlock):
    left_text = blocks.RichTextBlock(label="levý sloupec", features=RICH_TEXT_FEATURES)
    right_text = blocks.RichTextBlock(
        label="pravý sloupec", features=RICH_TEXT_FEATURES
    )

    class Meta:
        label = "text dva sloupce"
        icon = "doc-full"
        template = "uniweb/blocks/text_columns.html"


class AdvancedColumnsTextBlock(ColorBlock):
    left_text = blocks.RichTextBlock(label="levý sloupec", features=RICH_TEXT_FEATURES)
    right_text = blocks.RichTextBlock(
        label="pravý sloupec", features=RICH_TEXT_FEATURES
    )

    class Meta:
        label = "text dva sloupce (pokročilý)"
        icon = "doc-full"
        template = "uniweb/blocks/advanced_text_columns.html"


class AdvancedTitleBlock(ColorBlock):
    title = blocks.CharBlock(label="nadpis")

    class Meta:
        label = "nadpis (pokročilý)"
        icon = "title"
        template = "uniweb/blocks/advanced_title.html"


class AdvancedTextBlock(ColorBlock):
    text = blocks.RichTextBlock(label="text", features=RICH_TEXT_FEATURES)

    class Meta:
        label = "text (pokročilý)"
        icon = "doc-full"
        template = "uniweb/blocks/advanced_text.html"


class MenuItemBlock(blocks.StructBlock):
    name = blocks.CharBlock(label="název")
    page = blocks.PageChooserBlock(
        label="stránka",
        page_type=["uniweb.UniwebHomePage", "uniweb.UniwebFlexiblePage"],
    )

    class Meta:
        label = "stránka"


class SubpageMixin:
    """Must be used in class definition before MetadataPageMixin!"""

    @property
    def root_page(self):
        if not hasattr(self, "_root_page"):
            self._root_page = self.get_ancestors().type(UniwebHomePage).specific().get()
        return self._root_page

    def get_meta_image(self):
        return self.search_image or self.root_page.get_meta_image()


class UniwebContentMixin(models.Model):
    content = StreamField(
        [
            ("title", blocks.CharBlock(label="nadpis", icon="title")),
            ("advanced_title", AdvancedTitleBlock()),
            ("text", blocks.RichTextBlock(label="text", features=RICH_TEXT_FEATURES)),
            ("advanced_text", AdvancedTextBlock()),
            ("text_columns", ColumnsTextBlock()),
            ("advanced_text_columns", AdvancedColumnsTextBlock()),
            (
                "gallery",
                blocks.ListBlock(
                    ImageChooserBlock(label="obrázek"), label="galerie", icon="image"
                ),
            ),
            (
                "table",
                TableBlock(
                    label="tabulka",
                    template="uniweb/snippet_table.html",
                ),
            ),
            ("jupyter", DocumentChooserBlock(label="Jupyter notebook")),
        ],
        verbose_name="obsah stránky",
        blank=True,
    )

    class Meta:
        abstract = True


class UniwebHomePage(Page, UniwebContentMixin, MetadataPageMixin):
    ### FIELDS

    # settings
    matomo_id = models.IntegerField(
        "Matomo ID pro sledování návštěvnosti", blank=True, null=True
    )
    top_menu = StreamField(
        [("item", MenuItemBlock())],
        verbose_name="horní menu",
        blank=True,
    )

    ### PANELS

    content_panels = Page.content_panels + [
        StreamFieldPanel("content"),
    ]

    promote_panels = [
        MultiFieldPanel(
            [
                FieldPanel("seo_title"),
                FieldPanel("search_description"),
                ImageChooserPanel("search_image"),
                HelpPanel(help.build(help.IMPORTANT_TITLE)),
            ],
            gettext_lazy("Common page configuration"),
        ),
    ]

    settings_panels = [
        FieldPanel("matomo_id"),
        StreamFieldPanel("top_menu"),
    ]

    ### RELATIONS

    subpage_types = [
        "uniweb.UniwebFlexiblePage",
    ]

    ### OTHERS

    class Meta:
        verbose_name = "Univerzální web"

    @property
    def root_page(self):
        return self


class UniwebFlexiblePage(Page, UniwebContentMixin, SubpageMixin, MetadataPageMixin):
    ### FIELDS

    ### PANELS

    promote_panels = [
        MultiFieldPanel(
            [
                FieldPanel("slug"),
                FieldPanel("seo_title"),
                FieldPanel("search_description"),
                ImageChooserPanel("search_image"),
                HelpPanel(help.build(help.NO_SEO_TITLE, help.NO_SEARCH_IMAGE)),
            ],
            gettext_lazy("Common page configuration"),
        ),
    ]

    content_panels = Page.content_panels + [
        StreamFieldPanel("content"),
    ]

    settings_panels = []

    ### RELATIONS

    parent_page_types = ["uniweb.UniwebHomePage"]
    subpage_types = []

    ### OTHERS

    class Meta:
        verbose_name = "Flexibilní stránka"