import {WebSocketPayload} from "./WebSocketPayload";
import {WebSocketEvent} from "./WebSocketEvent";
import {iTender} from "./iTender";
import {Settings} from "./Settings";
import Container from "./database/Container";
import Job from "./database/Job";
import Drink from "./database/Drink";
import Ingredient from "./database/Ingredient";
import {RequestType} from "./RequestType";
import debug from "debug";

const log = debug("itender:WShandler");

export class WebSocketHandler {
    private static _ws: WebSocket|any;

    static get ws(): WebSocket {
        return this._ws;
    }

    static set ws(value: WebSocket|any) {
        this._ws = value;
    }

    public static send(payload: WebSocketPayload): Promise<void> {
        return new Promise(async (resolve, reject) => {
            try {
                if (this.ws && this.ws.readyState == 1) {
                    log("Sending " + payload.event);

                    await this.ws.send(payload.toString());
                    resolve();
                }
            } catch (e) {

            }
        });
    }

    public static answerRequest(type: RequestType, data: any) {

        WebSocketHandler.send(new WebSocketPayload(WebSocketEvent.RESPONSE, {type: type, data: data}));
        log("Answered " + type + " request");

    }

    public static sendStatus() {
        return new Promise(resolve => {
            let payload = new WebSocketPayload(WebSocketEvent.STATUS, {status: iTender.status});
            WebSocketHandler.send(payload).then(resolve);
        });
    }

    static sendRunningConfig() {
        return new Promise(resolve => {
            let payload = new WebSocketPayload(WebSocketEvent.CONFIG, Settings.json);
            WebSocketHandler.send(payload).then(resolve);
        });
    }

    static sendStats() {
        return new Promise(async resolve => {

            let counts: any[] = [];
            let drinks = await Drink.find();
            for (let drink of drinks) {
                console.log(drink._id);
                console.log( (await Job.countDocuments( )) );
                let count = await Job.countDocuments({drink: drink._id});
                console.log(count);

                counts.push([drink, count]);
            }


            counts = counts.sort((a, b) => {
                if (a[1] > b[1])
                    return -1;
                else if (a[1] < b[1])
                    return 1;
                else
                    return 0;
            });



            let stats = {
                "drinks_finished": (await Job.countDocuments({successful: true})),
                "drink_most": (counts.length == 0) ? "Keiner" : counts[0][0].name,
                "count_ingredients": (await Ingredient.countDocuments()),
                "count_cocktails": (await Drink.countDocuments())
            };
            let payload = new WebSocketPayload(WebSocketEvent.RESPONSE, {
                type: RequestType.STATS,
                data: stats
            });
            WebSocketHandler.send(payload).then(resolve);
        });
    }

    static sendContainers() {
        return new Promise(async resolve => {
            let payload = new WebSocketPayload(WebSocketEvent.CONTAINERS, (await Container.find().populate("content")));
            WebSocketHandler.send(payload).then(resolve);
        })
    }

    static sendDrinks() {
        return new Promise(async resolve => {
            let payload = new WebSocketPayload(WebSocketEvent.DRINKS, iTender.drinks);
            WebSocketHandler.send(payload).then(resolve);
        })
    }
}