import graphene
from django.db.models import Q
from graphene import relay
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField

from core.mixins import HiddenAndVisibleForMixin, HiddenForMixin
from objectives.models import ObjectiveGroup, Objective


class ObjectiveNode(DjangoObjectType, HiddenAndVisibleForMixin):
    pk = graphene.Int()
    user_created = graphene.Boolean()
    mine = graphene.Boolean()

    class Meta:
        model = Objective
        filter_fields = ['text']
        interfaces = (relay.Node,)

    def resolve_objective_progress(self, info, **kwargs):
        return self.objective_progress.filter(user=info.context.user)

    def resolve_user_created(self, info, **kwargs):
        return self.owner is not None

    def resolve_mine(self, info, **kwargs):
        return self.owner is not None and self.owner.pk == info.context.user.pk


class ObjectiveGroupNode(DjangoObjectType, HiddenForMixin):
    pk = graphene.Int()
    display_title = graphene.String()
    objectives = graphene.List(ObjectiveNode)

    class Meta:
        model = ObjectiveGroup
        filter_fields = ['title', 'module__slug']
        interfaces = (relay.Node,)

    def resolve_pk(self, *args, **kwargs):
        return self.id

    def resolve_display_title(self, *args, **kwargs):
        return self.get_title_display()

    def resolve_objectives(self, info, **kwargs):
        user = info.context.user
        school_classes = user.school_classes.values_list('pk')
        base_qs = self.objectives.filter(objectivesnapshot__isnull=True)

        objectives_from_publisher = Q(owner=None)
        objectives_from_user = Q(owner=user)
        objectives_from_teacher = Q(owner__isnull=False, visible_for__in=school_classes)

        # todo
        # raise NotImplemented('not in correct order')

        if user.has_perm('users.can_manage_school_class_content'):  # teacher
            return base_qs.filter(objectives_from_publisher | objectives_from_user)
        else:  # student
            return base_qs.filter(objectives_from_publisher | objectives_from_teacher)


class ObjectivesQuery(object):
    objective_group = relay.Node.Field(ObjectiveGroupNode)
    objective_groups = DjangoFilterConnectionField(ObjectiveGroupNode)
