import graphene
from graphene import relay
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField

from books.models import Topic, Module
from books.schema.nodes import ModuleNode


class NotFoundFailure:
    reason = "Not Found"


class NotFound(graphene.ObjectType):
    reason = graphene.String()


class TopicNode(DjangoObjectType):
    pk = graphene.Int()
    modules = DjangoFilterConnectionField(ModuleNode)

    class Meta:
        model = Topic
        only_fields = [
            "slug",
            "title",
            "teaser",
            "description",
            "vimeo_id",
            "order",
            "instructions",
        ]
        filter_fields = {
            "slug": ["exact", "icontains", "in"],
            "title": ["exact", "icontains", "in"],
        }
        interfaces = (relay.Node,)

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

    def resolve_modules(self, *args, **kwargs):
        translations = self.get_translations()
        ids = list(self.get_child_ids())
        for translation in translations:
            ids += list(translation.get_child_ids())
        return Module.objects.filter(id__in=ids).live()


class TopicOr404Node(graphene.Union):
    class Meta:
        types = (TopicNode, NotFound)

    @classmethod
    def resolve_type(cls, instance, info):
        if type(instance).__name__ == "Topic":
            return TopicNode
        return NotFound
