import graphene

from graphene_django.filter import DjangoFilterConnectionField
from graphene_django.types import DjangoObjectType
from graphql_relay.node.node import from_global_id

from .models import Building, Floor, Room


class BuildingNode(DjangoObjectType):
    real_id = graphene.Int()

    class Meta:
        model = Building
        interfaces = (graphene.Node, )
        filter_fields = {
            'name': ['icontains']
        }

    def resolve_real_id(self, args, context, info):
        return self.id


class FloorNode(DjangoObjectType):
    real_id = graphene.Int()

    class Meta:
        model = Floor
        interfaces = (graphene.Node, )
        filter_fields = ['number']

    def resolve_real_id(self, args, context, info):
        return self.id


class RoomNode(DjangoObjectType):
    real_id = graphene.Int()

    class Meta:
        model = Room
        interfaces = (graphene.Node, )
        filter_fields = {
            'name': ['icontains']
        }

    def resolve_real_id(self, args, context, info):
        return self.id


class BuildingQuery(graphene.AbstractType):
    buildings = DjangoFilterConnectionField(BuildingNode)
    floors = DjangoFilterConnectionField(FloorNode)
    rooms = DjangoFilterConnectionField(RoomNode)
    building = graphene.Field(BuildingNode, id=graphene.Int())
    floor = graphene.Field(FloorNode, id=graphene.Int())
    room = graphene.Field(RoomNode, id=graphene.Int())

    def resolve_building(self, args, context, info):
        id = args.get('id')
        if id is not None:
            return Building.objects.get(pk=id)
        return None

    def resolve_floors(self, args, context, info):
        return Floor.objects.select_related('building').all()

    def resolve_floor(self, args, context, info):
        id = args.get('id')
        if id is not None:
            return Floor.objects.get(pk=id)
        return None

    def resolve_rooms(self, args, context, info):
        return Room.objects.select_related('floor').all()


class Query(BuildingQuery, graphene.ObjectType):
    # This class will inherit from multiple Queries
    # as we begin to add more apps to our project
    pass

schema = graphene.Schema(query=Query)

import graphene

from graphene_django.filter import DjangoFilterConnectionField
from graphene_django.types import DjangoObjectType
from graphql_relay.node.node import from_global_id

from .models import Building, Floor, Room


class BuildingNode(DjangoObjectType):
    pk = graphene.Int()

    class Meta:
        model = Building
        interfaces = (graphene.Node, )
        filter_fields = {
            'name': ['icontains']
        }

    def resolve_pk(self, args, context, info):
        return self.id


class CreateBuilding(graphene.Mutation):
    class Input:
        name = graphene.String(required=True)
        size = graphene.Int(required=True)

    ok = graphene.Boolean()
    building = graphene.Field(BuildingNode)

    @staticmethod
    def mutate(root, args, context, info):
        building = Building.objects.create(name=args.get('name'), size=args.get('size'))
        ok = True
        return CreateBuilding(building=building, ok=ok)


class FloorNode(DjangoObjectType):
    pk = graphene.Int()

    class Meta:
        model = Floor
        interfaces = (graphene.Node, )
        filter_fields = ['number']

    def resolve_pk(self, args, context, info):
        return self.id


class RoomNode(DjangoObjectType):
    pk = graphene.Int()

    class Meta:
        model = Room
        interfaces = (graphene.Node, )
        filter_fields = {
            'name': ['icontains']
        }

    def resolve_pk(self, args, context, info):
        return self.id


class Query(graphene.ObjectType):
    buildings = DjangoFilterConnectionField(BuildingNode)
    floors = DjangoFilterConnectionField(FloorNode)
    rooms = DjangoFilterConnectionField(RoomNode)
    building = graphene.Node.Field(BuildingNode)
    floor = graphene.Node.Field(FloorNode)
    room = graphene.Node.Field(RoomNode)


class Mutation(graphene.ObjectType):
    create_building = CreateBuilding.Field()


schema = graphene.Schema(query=Query, mutation=Mutation)

clean up query