import { ApolloServer } from "apollo-server/dist";
import { Resolvers, ChangePizzaDto, ChangeToppingDto } from "./generated/graphql";
import { pizzaSchema } from "./schema/schema";
import { PizzaResolver } from "./resolver/pizza-resolver";
import { ToppingResolver } from "./resolver/topping-resolver";

const resolvers: Resolvers = {
    Topping: {
        id: (root, _args, _context) => {
            return root.id
        },
        name: (root, _args, _context) => {
            return root.name
        },
    },
    Pizza: {
        id: (root, _args, _context) => {
            return root.id
        },
        name: (root, _args, _context) => {
            return root.name
        },
        toppings: (root, _args, _context) => {
            return root.toppings
        },
    },
    Query: {
        getPizzaById: (_root, args, _context) => {
            return PizzaResolver.getById(args.pizzaId);
        },
        getPizzaByName: (_root, args, _context) => {
            return PizzaResolver.getByName(args.pizzaName);
        },
        listPizza: (_root, _args, _context) => {
            return PizzaResolver.list();
        },
        getToppingById: (_root, args, _context) => {
            return ToppingResolver.getById(args.toppingId);
        },
        getToppingByName: (_root, args, _context) => {
            return ToppingResolver.getByName(args.toppingName);
        },
        listTopping: (_root, _args, _context) => {
            return ToppingResolver.list();
        },
    },
    Mutation: {
        createPizza: (_root, args, _context) => {
            return PizzaResolver.create(args.createPizzaDto as ChangePizzaDto);
        },
        updatePizza: (_root, args, _context) => {
            return PizzaResolver.update(args.pizzaId, args.updatedPizzaDto as ChangePizzaDto);
        },
        deletePizza: (_root, args, _context: any) => {
            return PizzaResolver.delete(args.pizzaId);
        },
        createTopping: (_root, args, _context) => {
            return ToppingResolver.create(args.createToppingDto as ChangeToppingDto);
        },
        updateTopping: (_root, args, _context) => {
            return ToppingResolver.update(args.toppingId, args.updatedToppingDto as ChangeToppingDto);
        },
        deleteTopping: (_root, args, _context: any) => {
            return ToppingResolver.delete(args.toppingId);
        },
    },
    Subscription: {
        pizzasChanged: {
            subscribe: () => PizzaResolver.pizzaEvent.asyncIterator(PizzaResolver.events.PIZZA_CHANGED)

        },
        toppingsChanged: {
            subscribe: () => ToppingResolver.toppingEvent.asyncIterator(ToppingResolver.events.TOPPING_CHANGED)
        },
    }
}

const server = new ApolloServer({
    typeDefs: pizzaSchema,
    resolvers: resolvers as any,
});

server.listen().then(({ url, subscriptionsUrl }) => {
    console.log(`🚀 Server ready at ${url}`)
    console.log(`🚀 Subscriptions ready at ${subscriptionsUrl}`);
});