import {Modal} from "./Modal";
import {WebSocketEvent} from "../WebSocketEvent";
import {WebSocketPayload} from "../WebSocketPayload";
import {ButtonType} from "./ButtonType";
import {iTenderStatus} from "../iTenderStatus";
import {WebHandler} from "./WebHandler";
import {Setup} from "./Setup";

export class WebWebSocketHandler {
    private static socket: WebSocket;
    private static url = (window.location.protocol == "http:" ? "ws://" : "wss://") + window.location.hostname + ":3005";
    public static tareContainerUpdates: (payload: WebSocketPayload) => void;



    constructor() {
        WebWebSocketHandler.socket = new WebSocket(WebWebSocketHandler.url);
        WebWebSocketHandler.socket.onopen = this.onOpen;
        WebWebSocketHandler.socket.onclose = this.onClose;
        WebWebSocketHandler.socket.onerror = this.onError;
        WebWebSocketHandler.socket.onmessage = this.onMessage;
    }

    private onMessage(msgEvent: MessageEvent) {
        console.log("[WS] Incoming message", msgEvent);
        let payload = WebSocketPayload.parseFromBase64Json(msgEvent.data);
        if (!payload) {
            console.log("[WS] Could not parse message: ", msgEvent);
            return;
        }
        console.log("[WS] Received " + payload.event + " Event");

        switch (payload.event) {
            case WebSocketEvent.CONFIG: {
                // Incoming WebSocketStatus
                Setup.onConfigUpdate(payload);
                break;
            }

            case WebSocketEvent.STATUS: {
                let statusElement = document.getElementById("status");
                if (statusElement)
                    statusElement.innerText = payload.data.status;

                let status: iTenderStatus = payload.data.status;

                switch (status) {
                    case iTenderStatus.READY: {
                        Modal.close("start");
                        Modal.close("refreshing");
                        Modal.close("setup");
                        break;
                    }
                    case iTenderStatus.STARTING: {
                        let modal = new Modal("start", "Willkommen!");
                        let txt = document.createElement("p");
                        txt.innerHTML = `Einen Augenblick bitte<br>iTender startet...`;
                        modal.addContent(txt);
                        modal.loader = true;
                        modal.open();
                        break;
                    }
                    case iTenderStatus.REFRESHING: {
                        let modal = new Modal("refreshing", "Aktualisieren...");
                        let txt = document.createElement("p");
                        txt.innerHTML = `Einen Augenblick bitte<br>iTender aktualisiert die Getränke...`;
                        modal.addContent(txt);
                        modal.loader = true;
                        modal.open();
                        break;
                    }
                    case iTenderStatus.SETUP: {
                        Setup.openSetup();
                    }
                }
                break;
            }

            case WebSocketEvent.DRINKS: {
                WebHandler.onDrinkUpdate(payload);
                break;
            }

            case WebSocketEvent.CONTAINERS: {
                WebHandler.onContainerUpdate(payload);
                break;
            }
        }
    }

    private onOpen(event) {
        console.log("[WS] Connected", event);

        /*let connectionElement = document.getElementById("right");
        if (connectionElement) {
            connectionElement.innerText = "Verbunden";
            connectionElement.style.color = "green";
        }*/

    }

    private onClose(event) {
        console.error("[WS] Closed!", event);
        if (event.wasClean) {
            let modal = new Modal("socketClosed", "Sitzung beendet!");
            let txt = document.createElement("p");
            txt.innerHTML = `Diese Sitzung wurde beendet, da der iTender nun an einem anderen Gerät bzw. an dem Hauptgerät gesteuert wird.<br><br>`;
            modal.addContent(txt);
            modal.addButton(ButtonType.PRIMARY, "Sitzung wiederherstellen", () => {
                window.location.reload();
            });
            modal.open();
        } else {
            let modal = new Modal("socketClosed", "Verbindungsproblem!");
            let txt = document.createElement("p");
            txt.innerHTML = `Die Benutzeroberfläche hat die Verbindung mit dem Gerät verloren.<br>Die Verbindung wird wiederhergestellt...<br>`;
            modal.addContent(txt);
            modal.loader = true;
            modal.open();
            setInterval(() => {
                window.location.reload();
            }, 5000);
        }

        /* let connectionElement = document.getElementById("right");
         if (connectionElement) {
             connectionElement.innerText = "Getrennt";
             connectionElement.style.color = "red";
         }*/
    }

    private onError(event) {
        console.error("[WS] Error", event);
        /*let connectionElement = document.getElementById("right");
        if (connectionElement)
            connectionElement.innerText = "Fehler";*/
        //openModal("Einen Augenblick...", `Es wurde ein kritischer Fehler festgestellt.\nBitte warten Sie, während der Prozess neu gestartet wird...` );
        //window.location.reload();
    }

    public static send(payload: WebSocketPayload): Promise<void> {
        return new Promise(async (resolve, reject) => {
            try {
                if (this.socket && this.socket.readyState == 1) {
                    await this.socket.send(payload.toString());
                    resolve();
                }
            } catch (e) {
                /*let modal = new Modal("error", "Verbindungsfehler");
                let txt = document.createElement("p");
                txt.innerHTML = `Beim Austausch von Informationen ist ein Problem aufgetreten.<br>Falls dies öfter passieren sollte, ist der Support zu kontaktieren.`;
                modal.addContent(txt);
                await modal.open();*/
                reject();
            }
        });
    }


}