import graphene
from django.db.models import Q
from graphene import relay

from api.utils import get_object
from books.models import Module, ContentBlock, Chapter
from books.models.snapshot import Snapshot
from books.schema.nodes import SnapshotNode, ModuleNode
from users.models import SchoolClass


class CreateSnapshot(relay.ClientIDMutation):
    class Input:
        module = graphene.String(required=True)
        selected_class = graphene.ID(required=True)

    snapshot = graphene.Field(SnapshotNode)
    success = graphene.Boolean()

    @classmethod
    def mutate_and_get_payload(cls, root, info, **args):
        module_slug = args.get('module')
        module = Module.objects.get(slug=module_slug)
        user = info.context.user
        # todo: check user
        # raise NotImplementedError('Permissions')
        selected_class_id = args.get('selected_class')
        selected_class = get_object(SchoolClass, selected_class_id)
        snapshot = Snapshot.objects.create_snapshot(module, selected_class, user)
        return cls(snapshot=snapshot, success=True)


class ApplySnapshot(relay.ClientIDMutation):
    class Input:
        snapshot = graphene.ID(required=True)
        selected_class = graphene.ID(required=True)

    success = graphene.Boolean()
    module = graphene.Field(ModuleNode)

    @classmethod
    def mutate_and_get_payload(cls, root, info, **args):
        snapshot_id = args.get('snapshot')
        snapshot = get_object(Snapshot, snapshot_id)
        user = info.context.user
        selected_class_id = args.get('selected_class')
        selected_class = get_object(SchoolClass, selected_class_id)
        # permission check
        if not selected_class.users.filter(username=user.username).exists() or not user.is_teacher():
            raise PermissionError('Not allowed')

        # reset everything
        snapshot.reset(user, selected_class)
        # apply snapshot
        snapshot.apply(user, selected_class)
        return cls(success=True, module=snapshot.module)


class ShareSnapshot(relay.ClientIDMutation):
    class Input:
        snapshot = graphene.ID(required=True)
        shared = graphene.Boolean(required=True)

    success = graphene.Boolean(required=True)
    snapshot = graphene.Field(SnapshotNode)

    @classmethod
    def mutate_and_get_payload(cls, root, info, **args):
        snapshot_id = args.get('snapshot')
        shared = args.get('shared')
        user = info.context.user
        snapshot = get_object(Snapshot, snapshot_id)
        if snapshot.creator != user:
            raise PermissionError('Not permitted')
        snapshot.shared = shared
        snapshot.save()
        return cls(success=True, snapshot=snapshot)
