import { Topping, Pizza, ChangePizzaDto, Maybe } from "../generated/graphql";
import { PizzaList } from "../data/pizza-list";
import { v4 as uuidv4 } from 'uuid';
import { ToppingResolver } from "./topping-resolver";
import { PubSub } from "apollo-server";

export class PizzaResolver {

    static pizzaEvent = new PubSub();
    static events = {
        PIZZA_CHANGED: "pizzaChanged",
    }    

    static getById = (id: string): Pizza => {
        return PizzaList.filter(pizza => pizza.id === id)[0];
    };

    static delete = (id: string): Pizza => {
        const index = PizzaList.indexOf(PizzaResolver.getById(id));
        if ( index ) {
            PizzaList.splice(index, 1)
        }
        return PizzaResolver.getById(id)
    };


    static list = (): Pizza[] => {
        return PizzaList;
    };

    static getByName = (name: string): Pizza => {
        return PizzaList.filter(pizza => pizza.name === name)[0];
    };

    static create = (pizzaCreateDto: ChangePizzaDto): Pizza => {
        // Get Topping Objects by Ids
        const toppings: Topping[] = pizzaCreateDto.toppingIds
            .map<string>((toppingId) => toppingId as string)
            .map<Topping>((toppingId) => ToppingResolver.getById(toppingId));
        // Init new Pizza Object
        const pizza: Pizza = {
            id: uuidv4(),
            name: pizzaCreateDto.name,
            toppings: toppings
        }
        // Add Pizza to 'Database'
        PizzaList.push(pizza);
        PizzaResolver.pizzaEvent.publish(PizzaResolver.events.PIZZA_CHANGED, {
            pizzasChanged: PizzaList
        });
        console.log(`Create Pizza ...`, pizza)
        return pizza;
    };

    static update = (pizzaId: string, pizzaUpdateDto: ChangePizzaDto): Pizza => {
        const pizza = PizzaResolver.getById(pizzaId);
        if (!pizza) {
            throw new Error(
                `No Pizza found with id ${pizzaId}`
            )
        }
        const toppings: Topping[] = pizzaUpdateDto.toppingIds
            .map<string>((toppingId: Maybe<string>) => toppingId as string)
            .map<Topping>((toppingId: string) => ToppingResolver.getById(toppingId));
        pizza.name = pizzaUpdateDto.name;
        pizza.toppings = toppings;
        const pizzaIndex = PizzaList.indexOf(pizza);
        PizzaList[pizzaIndex] = pizza;
        console.log(`Update Pizza ...`, pizza)
        PizzaResolver.pizzaEvent.publish(PizzaResolver.events.PIZZA_CHANGED, {
            pizzasChanged: PizzaList
        });
        return pizza;
    };

}