import logging

from django.db import models
from wagtail.admin.edit_handlers import FieldPanel, TabbedInterface, ObjectList, StreamFieldPanel
from wagtail.core.blocks import StreamBlock
from wagtail.core.fields import StreamField
from wagtail.images.blocks import ImageChooserBlock

from books.blocks import TextBlock, BasicKnowledgeBlock, LinkBlock, VideoBlock, DocumentBlock, \
    ImageUrlBlock, AssignmentBlock, InfogramBlock, GeniallyBlock, SubtitleBlock, SurveyBlock, ModuleRoomSlugBlock, \
    ThinglinkBlock, InstructionBlock
from books.utils import get_type_and_value
from core.wagtail_utils import StrictHierarchyPage
from notes.models import ContentBlockBookmark
from surveys.models import Survey
from users.models import SchoolClass, User

logger = logging.getLogger(__name__)


class ContentBlock(StrictHierarchyPage):
    class Meta:
        verbose_name = 'Inhaltsblock'
        verbose_name_plural = 'Inhaltsblöcke'

    NORMAL = 'normal'
    BASE_COMMUNICATION = 'base_communication'
    TASK = 'task'
    BASE_SOCIETY = 'base_society'
    BASE_INTERDISCIPLINARY = 'base_interdisciplinary'

    TYPE_CHOICES = (
        (NORMAL, 'Normal'),
        (BASE_COMMUNICATION, 'Instrument Sprache & Kommunikation'),
        (TASK, 'Auftrag'),
        (BASE_SOCIETY, 'Instrument Gesellschaft'),
        (BASE_INTERDISCIPLINARY, 'Überfachliches Instrument'),
    )

    # blocks without owner are visible by default, need to be hidden for each class
    hidden_for = models.ManyToManyField(SchoolClass, related_name='hidden_content_blocks')
    # blocks with owner are hidden by default, need to be shown for each class
    visible_for = models.ManyToManyField(SchoolClass, related_name='visible_content_blocks')
    user_created = models.BooleanField(default=False)
    original_creator = models.ForeignKey(User, null=True, blank=True, default=None, on_delete=models.SET_NULL)

    bookmarks = models.ManyToManyField(User, through=ContentBlockBookmark, related_name='bookmarked_content_blocks')

    content_blocks = [
        ('text_block', TextBlock()),
        ('basic_knowledge', BasicKnowledgeBlock()),
        ('assignment', AssignmentBlock()),
        ('survey', SurveyBlock()),
        ('image_block', ImageChooserBlock()),
        ('image_url_block', ImageUrlBlock()),
        ('link_block', LinkBlock()),
        ('solution', TextBlock(icon='tick')),
        ('video_block', VideoBlock()),
        ('document_block', DocumentBlock()),
        ('infogram_block', InfogramBlock()),
        ('genially_block', GeniallyBlock()),
        ('thinglink_block', ThinglinkBlock()),
        ('subtitle', SubtitleBlock()),
        ('instruction', InstructionBlock()),
        ('module_room_slug', ModuleRoomSlugBlock())
    ]

    content_list_item = StreamBlock(content_blocks)
    contents = StreamField(content_blocks + [('content_list_item', content_list_item)], null=True, blank=True)

    type = models.CharField(
        max_length=100,
        choices=TYPE_CHOICES,
        default=NORMAL
    )

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

    settings_panels = [
        FieldPanel('slug')
    ]

    edit_handler = TabbedInterface([
        ObjectList(content_panels, heading='Content'),
        ObjectList(settings_panels, heading='Settings'),
    ])

    template = 'generic_page.html'

    parent_page_types = ['books.Chapter']
    subpage_types = []

    @property
    def module(self):
        return self.get_parent().get_parent().specific

    def is_hidden_for_class(self, school_class):
        return (
                   not self.user_created and self.hidden_for.filter(id=school_class.id).exists()
               ) or (
                   self.user_created and not self.visible_for.filter(id=school_class.id).exists()
               )

    def save(self, *args, **kwargs):
        for data in self.contents.stream_data:
            block_type, value = get_type_and_value(data)

            if block_type == 'survey':
                module = self.module
                survey = value['survey_id']
                if isinstance(survey, int):
                    survey = Survey.objects.get(pk=survey)
                if survey.module != module:
                    survey.module = module
                    survey.save()
        super().save(*args, **kwargs)


class ContentBlockSnapshot(ContentBlock):
    hidden = models.BooleanField(default=False)
    snapshot = models.ForeignKey(
        'books.snapshot',
        on_delete=models.SET_NULL,
        null=True,
        related_name='custom_content_blocks'
    )

    def to_regular_content_block(self, owner, school_class):
        cb = ContentBlock(
            contents=self.contents,
            type=self.type,
            title=self.title,
            owner=owner,
            original_creator=self.original_creator,
            user_created=True
        )
        self.add_sibling(instance=cb, pos='right')
        # some wagtail magic
        revision = cb.save_revision()
        revision.publish()
        cb.visible_for.add(school_class)
        cb.save()

        return cb
