# Create your models here.

from django.utils.text import slugify
from wagtail import blocks
from wagtail.blocks import StreamBlock
from wagtail.fields import StreamField
from wagtail.images.blocks import ImageChooserBlock
from wagtail.models import Page, Orderable

from vbv_lernwelt.learnpath.models_competences import *
from vbv_lernwelt.learnpath.models_learning_unit_content import WebBasedTrainingBlock, VideoBlock, PodcastBlock, \
    CompetenceBlock, ExerciseBlock, DocumentBlock, KnowledgeBlock
from vbv_lernwelt.learnpath.serializer_helpers import get_it_serializer_class


class LearningPath(Page):
    # PageChooserPanel('related_page', 'demo.PublisherPage'),

    content_panels = Page.content_panels
    subpage_types = ['learnpath.Circle', 'learnpath.Topic']

    class Meta:
        verbose_name = "Learning Path"

    def full_clean(self, *args, **kwargs):
        self.slug = find_available_slug(Page, slugify(self.title, allow_unicode=True))
        super(LearningPath, self).full_clean(*args, **kwargs)

    def __str__(self):
        return f"{self.title}"

    @classmethod
    def get_serializer_class(cls):
        return get_it_serializer_class(
            cls, ['id', 'title', 'slug', 'type', 'translation_key', 'children']
        )


class Topic(Page):
    # title = models.TextField(default='')
    is_visible = models.BooleanField(default=True)

    parent_page_types = ['learnpath.LearningPath']

    panels = [FieldPanel('title'),
              FieldPanel('is_visible'),
              ]

    # content_panels = Page.content_panels + [
    #     FieldPanel('is_visible', classname="full"),
    #     PageChooserPanel('learning_path',  'learnpath.LearningPath'),
    # ]

    # parent_page_types = ['learnpath.LearningPath']
    # subpage_types = ['learnpath.Circle']

    def full_clean(self, *args, **kwargs):
        self.slug = find_available_slug(Topic, slugify(self.title, allow_unicode=True))
        print(self.slug)
        super(Topic, self).full_clean(*args, **kwargs)

    @classmethod
    def get_serializer_class(cls):
        return get_it_serializer_class(
            cls, field_names=['id', 'title', 'slug', 'type', 'translation_key', 'is_visible', ]
        )

    class Meta:
        verbose_name = "Topic"

    def __str__(self):
        return f"{self.title}"


class PersonBlock(blocks.StructBlock):
    first_name = blocks.CharBlock()
    last_name = blocks.CharBlock()
    email = blocks.EmailBlock()
    photo = ImageChooserBlock(required=False)
    biography = blocks.RichTextBlock(required=False)

    class Meta:
        icon = 'user'


class Circle(Page):
    description = models.TextField(default="", blank=True)
    goals = StreamField([
        ('goal', blocks.TextBlock()),
    ], use_json_field=True)
    job_situations = StreamField([
        ('job_situation', blocks.CharBlock()),
    ], use_json_field=True)
    experts = StreamField([
        ('person', PersonBlock()),
    ], use_json_field=True)

    parent_page_types = ['learnpath.LearningPath']
    subpage_types = ['learnpath.LearningSequence', 'learnpath.LearningUnit', 'learnpath.LearningContent']

    content_panels = Page.content_panels + [
        FieldPanel('description'),
        FieldPanel('goals'),
        FieldPanel('job_situations'),
        FieldPanel('experts'),
    ]

    @classmethod
    def get_serializer_class(cls):
        return get_it_serializer_class(
            cls,
            field_names=[
                'id', 'title', 'slug', 'type', 'translation_key', 'children',
                'description', 'job_situations', 'goals', 'experts',
            ]
        )

    def full_clean(self, *args, **kwargs):
        # TODO: why own slug function?
        self.slug = find_available_slug(Page, slugify(self.title, allow_unicode=True))
        super(Circle, self).full_clean(*args, **kwargs)

    class Meta:
        verbose_name = "Circle"

    def __str__(self):
        return f"{self.title}"


class LearningSequence(Page):
    parent_page_types = ['learnpath.Circle']
    subpage_types = []

    icon = models.CharField(max_length=255, default="it-icon-ls-start")

    content_panels = Page.content_panels + [
        FieldPanel('icon'),
    ]

    class Meta:
        verbose_name = "Learning Sequence"

    def __str__(self):
        return f"{self.title}"

    @classmethod
    def get_serializer_class(cls):
        return get_it_serializer_class(cls, field_names=['id', 'title', 'slug', 'type', 'translation_key', 'icon'])

    def get_admin_display_title(self):
        return f'{self.icon} {self.draft_title}'

    def get_admin_display_title_html(self):
        return f'''
          <span style="display: inline-flex; align-items: center; font-size: 1.25rem; font-weight: 700;">
            <{self.icon} style="height: 32px; width: 32px;"></{self.icon}>
            <span style="margin-left: 8px;">{self.draft_title}</span>
          </span>'''

    def full_clean(self, *args, **kwargs):
        super(LearningSequence, self).full_clean(*args, **kwargs)


class LearningUnit(Page):
    parent_page_types = ['learnpath.Circle']
    subpage_types = []

    class Meta:
        verbose_name = "Learning Unit"

    def __str__(self):
        return f"{self.title}"

    @classmethod
    def get_serializer_class(cls):
        return get_it_serializer_class(cls, field_names=['id', 'title', 'slug', 'type', 'translation_key', 'children'])

    def get_admin_display_title_html(self):
        return f'<span style="font-weight: 700; font-size: 20px;">{self.draft_title}</span>'


class LearningUnitQuestion(Page):
    parent_page_types = ['learnpath.LearningUnit']
    subpage_types = []

    class Meta:
        verbose_name = "Learning Unit Question"

    def __str__(self):
        return f"{self.title}"

    @classmethod
    def get_serializer_class(cls):
        return get_it_serializer_class(cls, field_names=['id', 'title', 'slug', 'type', 'translation_key', ])


class LearningContent(Page):
    parent_page_types = ['learnpath.Circle']
    subpage_types = []

    minutes = models.PositiveIntegerField(default=15)

    content_blocks = [
        ('video', VideoBlock()),
        ('web_based_training', WebBasedTrainingBlock()),
        ('podcast', PodcastBlock()),
        ('competence', CompetenceBlock()),
        ('exercise', ExerciseBlock()),
        ('document', DocumentBlock()),
        ('knowledge', KnowledgeBlock()),
    ]

    contents = StreamField(
        StreamBlock(content_blocks), blank=False, min_num=1, max_num=1
    )

    content_panels = [
        FieldPanel('title', classname="full title"),
        FieldPanel('minutes'),
        StreamFieldPanel('contents'),
    ]

    def get_admin_display_title(self):
        display_title = ''

        if len(self.contents) > 0:
            display_title += f'{self.contents[0].block_type.capitalize()}: '

        display_title += self.draft_title

        return display_title

    def get_admin_display_title_html(self):
        return f'''
          <span style="display: inline-flex; align-items: center;">
            <it-icon-checkbox-unchecked style="height: 24px; width: 24px;"></it-icon-checkbox-unchecked>
            <span style="margin-left: 8px;">{self.get_admin_display_title()}</span>
          </span>'''

    class Meta:
        verbose_name = "Learning Content"

    def full_clean(self, *args, **kwargs):
        self.slug = find_available_slug(LearningContent, slugify(self.title, allow_unicode=True))
        super(LearningContent, self).full_clean(*args, **kwargs)

    @classmethod
    def get_serializer_class(cls):
        return get_it_serializer_class(cls,
                                       field_names=['id', 'title', 'slug', 'type',
                                                    'translation_key', 'minutes', 'contents'])

    def __str__(self):
        return f"{self.title}"


def find_available_slug(model, requested_slug, ignore_page_id=None):
    """
    Finds an available slug within the specified parent.

    If the requested slug is not available, this adds a number on the end, for example:

     - 'requested-slug'
     - 'requested-slug-1'
     - 'requested-slug-2'

    And so on, until an available slug is found.

    The `ignore_page_id` keyword argument is useful for when you are updating a page,
    you can pass the page being updated here so the page's current slug is not
    treated as in use by another page.
    """

    # TODO: In comparison ot wagtails own function, I look for the same model  instead of the parent
    pages = model.objects.filter(slug__startswith=requested_slug)

    if ignore_page_id:
        pages = pages.exclude(id=ignore_page_id)

    existing_slugs = set(pages.values_list("slug", flat=True))
    slug = requested_slug
    number = 1

    while slug in existing_slugs:
        slug = requested_slug + "-" + str(number)
        number += 1

    return slug
