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 {IDrink} from "./database/IDrink";
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;

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

    static set ws(value: WebSocket) {
        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, content: any) {
        WebSocketHandler.send(new WebSocketPayload(WebSocketEvent.RESPONSE, false, {type: type, content: content}));

    }

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

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

    static sendStats() {
        return new Promise(async resolve => {
            let counts: IDrink[] = [];
            for (let drink of (await Drink.find())) {
                // @ts-ignore
                drink.count = (await Job.countDocuments({drink: drink}));
                counts.push(drink)
            }
            counts.sort((a: IDrink, b: IDrink) => {
                // @ts-ignore
                if (a.count < b.count)
                    return -1;
                // @ts-ignore
                else if (a.count > b.count)
                    return 1;
                else
                    return 0;
            });

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

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

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