from django.contrib.auth import get_user_model
from django.db import models

from books.models import Module
from core.utils import sync_visible_for, sync_hidden_for
from users.models import SchoolClass


class ObjectiveGroup(models.Model):
    class Meta:
        verbose_name = 'Lernzielgruppe'
        verbose_name_plural = 'Lernzielgruppen'

    LANGUAGE_COMMUNICATION = 'language_communication'
    SOCIETY = 'society'
    INTERDISCIPLINARY = 'interdisciplinary'

    TITLE_CHOICES = (
        (LANGUAGE_COMMUNICATION, 'Sprache & Kommunikation'),
        (SOCIETY, 'Gesellschaft'),
        (INTERDISCIPLINARY, 'Überfachliche Lernziele'),
    )

    title = models.CharField('title', blank=True, null=False, max_length=255, choices=TITLE_CHOICES,
                             default=LANGUAGE_COMMUNICATION)
    module = models.ForeignKey(Module, blank=False, null=False, on_delete=models.CASCADE,
                               related_name='objective_groups')

    hidden_for = models.ManyToManyField(SchoolClass, related_name='hidden_objective_groups', blank=True)

    def __str__(self):
        return '{} - {}'.format(self.module, self.title)

    def sync_visibility(self, school_class_template, school_class_to_sync):
        # if self.hidden_for.filter(id=school_class_template.id).exists() and not self.hidden_for.filter(id=school_class_to_sync.id).exists():
        #     self.hidden_for.add(school_class_to_sync)
        #
        # if self.hidden_for.filter(id=school_class_to_sync.id).exists() and not self.hidden_for.filter(id=school_class_template.id).exists():
        #     self.hidden_for.remove(school_class_to_sync)
        sync_hidden_for(self, school_class_template, school_class_to_sync)

        for objective in self.objectives.all():
            objective.sync_visibility(school_class_template, school_class_to_sync)


class Objective(models.Model):
    class Meta:
        verbose_name = 'Lernziel'
        verbose_name_plural = 'Lernziele'
        # todo: reinstate ordering in resolver
        # ordering = [F('owner').asc(nulls_first=True), F('order').asc(nulls_last=True)]

    text = models.CharField('text', blank=True, null=False, max_length=255)
    group = models.ForeignKey(ObjectiveGroup, blank=False, null=False, on_delete=models.CASCADE,
                              related_name='objectives')
    owner = models.ForeignKey(get_user_model(), blank=True, null=True, on_delete=models.PROTECT)
    hidden_for = models.ManyToManyField(SchoolClass, related_name='hidden_objectives', blank=True)
    visible_for = models.ManyToManyField(SchoolClass, related_name='visible_objectives', blank=True)
    order = models.IntegerField(null=True, blank=True)

    def __str__(self):
        return 'Objective {}-{}'.format(self.id, self.text)

    def sync_visibility(self, school_class_template, school_class_to_sync):
        sync_hidden_for(self, school_class_template, school_class_to_sync)
        sync_visible_for(self, school_class_template, school_class_to_sync)

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


class ObjectiveSnapshot(Objective):
    hidden = models.BooleanField(default=False)
    snapshot = models.ForeignKey(
        'books.Snapshot',
        on_delete=models.SET_NULL,
        null=True,
        related_name='custom_objectives'
    )

    def to_regular_objective(self, owner, school_class):
        objective = Objective.objects.create(
            owner=owner,
            text=self.text,
            group=self.group,
            order=self.order
        )

        objective.visible_for.add(school_class)
        objective.save()

        return objective
