import graphene
from graphene import relay
from graphene_django.filter import DjangoFilterConnectionField
from wagtail.models import Locale

from api.utils import get_object
from core.logger import get_logger
from .connections import TopicConnection, ModuleConnection
from .nodes import (
    ContentBlockNode,
    ChapterNode,
    ModuleNode,
    NotFoundFailure,
    SnapshotNode,
    TopicOr404Node,
)
from .nodes.module_category import ModuleCategoryNode
from .nodes.module_level import ModuleLevelNode
from ..models import Book, Topic, Module, Chapter, Snapshot, ModuleLevel, ModuleCategory

logger = get_logger(__name__)


class BookQuery(object):
    node = relay.Node.Field()
    topic = graphene.Field(TopicOr404Node, slug=graphene.String())
    module = graphene.Field(ModuleNode, slug=graphene.String(), id=graphene.ID())
    chapter = relay.Node.Field(ChapterNode)
    content_block = relay.Node.Field(ContentBlockNode)
    snapshot = relay.Node.Field(SnapshotNode)

    topics = relay.ConnectionField(TopicConnection)
    modules = relay.ConnectionField(ModuleConnection)
    chapters = DjangoFilterConnectionField(ChapterNode)

    module_level = graphene.Field(ModuleLevelNode, id=graphene.ID(required=True))
    module_levels = graphene.List(ModuleLevelNode)

    module_category = graphene.Field(ModuleCategoryNode, id=graphene.ID(required=True))
    module_categories = graphene.List(ModuleCategoryNode)

    def resolve_books(self, *args, **kwargs):
        return Book.objects.filter(**kwargs).live()

    def resolve_topics(self, *args, **kwargs):
        default_locale = Locale.get_default()
        return Topic.objects.live().filter(locale=default_locale)

    def resolve_modules(self, *args, **kwargs):
        return Module.objects.filter(**kwargs).live()

    def resolve_chapters(self, *args, **kwargs):
        return Chapter.objects.filter(**kwargs).live()

    def resolve_snapshot(self, info, **kwargs):
        id = kwargs.get("id")
        snapshot = get_object(Snapshot, id)
        return snapshot

    def resolve_module(self, info, **kwargs):
        slug = kwargs.get("slug")
        id = kwargs.get("id")
        module = None
        try:
            if id is not None:
                module = get_object(Module, id)

            elif slug is not None:
                module = Module.objects.get(slug=slug)

            return module

        except Module.DoesNotExist:
            return None

    def resolve_topic(self, info, **kwargs):
        slug = kwargs.get("slug")
        id = kwargs.get("id")

        if id is not None:
            return get_object(Topic, id)
        if slug is not None:
            try:
                default_locale = Locale.get_default()
                return Topic.objects.get(slug=slug, locale=default_locale)
            except Topic.DoesNotExist:
                return NotFoundFailure
        return None

    def resolve_module_level(self, info, **kwargs):
        module_level_id = kwargs.get("id")
        try:
            if module_level_id is not None:
                return get_object(Module, module_level_id)

        except Module.DoesNotExist:
            return None

    def resolve_module_levels(self, *args, **kwargs):
        return ModuleLevel.objects.all()

    def resolve_module_category(self, info, **kwargs):
        id = kwargs.get("id")
        try:
            if id is not None:
                return get_object(Module, id)

        except Module.DoesNotExist:
            return None

    def resolve_module_categories(self, *args, **kwargs):
        return ModuleCategory.objects.all()


class ModuleTypeQuery(graphene.ObjectType):
    node = relay.Node.Field()
    name = graphene.String()
    id = graphene.ID()
