from django.db import models
from django.db.models.aggregates import Sum
from django.db.models.expressions import Case, When
from django.db.models.fields import IntegerField
from django.db.models.manager import Manager
from django.db.models.query import QuerySet
from django.template.defaultfilters import slugify
from django.utils.translation import gettext as _
from embed_video.fields import EmbedVideoField
from utils.general import normalize_polish_chars


class ExerciseQuerySet(QuerySet):
    def active(self):
        return self.filter(is_active=True)

    def annotated_with_done_by_apprentice(self, apprentice):
        return self.active().annotate(
            done=Sum(Case(When(apprentices=apprentice, then=1), default=0,
                          output_field=IntegerField())))

    def annotated_with_done_by_apprentice_count(self, apprentice):
        return self.annotated_with_done_by_apprentice(apprentice).aggregate(done_count=Sum('done'))['done_count']

    def from_path(self, path):
        return self.active().filter(tasks__path=path).distinct()

    def from_path_count(self, path):
        return self.from_path(path).count()

    def from_task(self, task):
        return task.exercises.active()

    def from_task_count(self, task):
        return self.from_task(task).count()


class ExerciseManager(Manager.from_queryset(ExerciseQuerySet)):
    pass


class Exercise(models.Model):
    title = models.CharField(max_length=70, verbose_name=_('tytuł'))
    text = models.TextField(blank=True, verbose_name=_('tekst'))
    is_active = models.BooleanField(default=True, verbose_name=_('czy aktywne?'))
    apprentices = models.ManyToManyField('users.Apprentice', blank=True, verbose_name=_(u'ukończone przez'))
    yt_video = EmbedVideoField(blank=True, null=True, verbose_name=_('link youtube'))

    objects = ExerciseManager()

    class Meta:
        verbose_name = _('ćwiczenie')
        verbose_name_plural = _('ćwiczenia')

    def slug(self):
        return slugify(normalize_polish_chars(self.title))

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