import { ApolloServer } from "apollo-server/dist";
import { Resolvers, ChangeToppingDto } from "./generated/graphql";
import { pizzaSchema } from "./schema/schema";
import { ToppingResolver } from "./resolver/topping-resolver";
import { MongoClient } from 'mongodb'
import PizzaDataSource from "./data-source/pizza.data-source";
import ToppingDataSource from "./data-source/topping-list";
import { ApolloServerExpressConfig } from "../../../../../Vorträge/Graphql/graphql-pizza-demo/backend/node_modules/apollo-server-express/dist";


const client = new MongoClient(process.env.DATABASE_URL as string)
client.connect()
export type Context = {
    PizzaApi: PizzaDataSource,
    ToppingApi: ToppingDataSource,
}

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: async (_, _args, context) => {
            return context.PizzaApi.findMany();
        },
        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(PIZZA_EVENTS.PIZZA_CHANGED)

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

const options: ApolloServerExpressConfig = {
    context: {

    },
    typeDefs: pizzaSchema,
    resolvers: resolvers as any,
    dataSources: (): Context => ({
        PizzaApi: new PizzaDataSource(client.db().collection('pizzas')),
        ToppingApi: new ToppingDataSource(client.db().collection('topping'))
    })
}

const server = new ApolloServer(options);

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