import {WebSocketPayload} from "../WebSocketPayload";
import {IDrink} from "../database/IDrink";
import {Modal} from "./Modal";
import {ButtonType} from "./ButtonType";
import {Pane} from "./Pane";
import {IContainer} from "../database/IContainer";
import {Setup} from "./Setup";
import * as Events from "events";
import {SensorType} from "../SensorType";

export class WebHandler {
    private static containers = [];

    public static onDrinkUpdate(payload: WebSocketPayload) {
        if (!payload.data) return;
        let drinks: IDrink[] = payload.data;

        const main = document.getElementById("main");
        if (!main) return;

        main.style.gridTemplateRows = `repeat(${Math.round(drinks.length / 3)}, calc(90%/2))`;

        main.innerHTML = "";

        for (let drink of drinks) {
            let drinkEle = document.createElement("div");
            drinkEle.classList.add("drink");


            let drinkImg = document.createElement("img");
            drinkImg.classList.add("thumbnail");
            drinkEle.append(drinkImg);

            let drinkName = document.createElement("p");
            drinkName.classList.add("drinkName");
            drinkEle.append(drinkName);

            drinkImg.alt = "Foto von " + drink.name;
            drinkImg.src = "/images/" + drink.name + ".png";
            drinkName.innerText = drink.name;

            /*
            let ingredients = "<ul style='list-style-type: disc;'>";
            for (let i of drink.ingredients) {
                ingredients += "<li>" + i.amount + "ml " + i.type.name + "</li>";
            }
            ingredients += "</ul>"

            drinkEle.onclick = () => {
                let modal = new Modal("drink", drink.name);

                modal.content = `<strong>Zutaten</strong><br>
${ingredients}`*/ //todo
            //modal.leftCentered = true;
            // modal.open();
            //};

            //main.append(drinkEle);
        }

    }


    public static onContainerUpdate(payload: WebSocketPayload) {
        let containerDiv = document.getElementById("setupContainers") as HTMLDivElement;
        containerDiv.innerHTML = "";

        let containers = payload.data as IContainer[];
        for (let c of containers) {
            Setup.addSetupContainer();
        }

        let i = 0;
        let list = containerDiv.getElementsByTagName("div");
        for (let c of containers) {
            let current = list[i] as HTMLDivElement;
            let selects = current.getElementsByTagName("select");

            (selects[0] as HTMLSelectElement).value = c.pumpPin.toString();
            let type;
            if( c.sensorType == SensorType.NONE )
                type = "-1";
            else if( c.sensorType == SensorType.ULTRASOUND )
                type = "0";
            else
                type = "1";
            (selects[1] as HTMLSelectElement).value = type;
            (selects[2] as HTMLSelectElement).value = c.sensorPin1.toString();
            (selects[3] as HTMLSelectElement).value = c.sensorPin2.toString();
            (selects[4] as HTMLSelectElement).value = c.volume.toString();
            let event = new Event('change', { bubbles: true });
            selects[1].dispatchEvent( event );

            i++;
        }

    }

    static async openSetup() {


        return;

        // old
        Modal.close();
        let modal = new Modal("setup", "Setup 1/2");

        let containers: { container: HTMLDivElement, slot: number, pumpPin: HTMLSelectElement, sensorType: HTMLSelectElement, sensorPin1: HTMLSelectElement, sensorPin2: HTMLSelectElement, volume: HTMLSelectElement }[] = [];

        let onchange = () => {
            let containerEle = document.getElementById("setup_containers") as HTMLDivElement;
            let containerNumber = document.getElementById("setup_slots") as HTMLInputElement;
            if (!containerEle || !containerNumber) return;

            let i = 1;
            let oldElements = containerEle.getElementsByTagName("div");
            for (let e of oldElements) {
                if (i > containerNumber.valueAsNumber) {
                    e.remove();
                    containers.pop();
                }
                i++;
            }

            for (let i = containerEle.getElementsByTagName("div").length; i < containerNumber.valueAsNumber; i++) {
                let con = document.createElement("div");
                let thisContainer = {};
                thisContainer["container"] = con;
                con.classList.add("setupContainer");

                let containerName = document.createElement("p");
                containerName.innerText = "Container " + (i + 1);
                thisContainer["slot"] = i + 1;

                con.append(containerName);

                let sensorTypeLabel = document.createElement("label");
                sensorTypeLabel.innerText = "Art des Sensors ";
                con.append(sensorTypeLabel);

                let sensorType = document.createElement("select");
                sensorType.classList.add("input");
                let sensorTypeNone = document.createElement("option") as HTMLOptionElement;
                sensorTypeNone.innerText = "Keiner";
                sensorTypeNone.value = "0";
                sensorType.append(sensorTypeNone);
                let sensorTypeUltrasound = document.createElement("option") as HTMLOptionElement;
                sensorTypeUltrasound.innerText = "Ultraschall";
                sensorTypeUltrasound.value = "1";
                sensorType.append(sensorTypeUltrasound);
                let sensorTypeScale = document.createElement("option") as HTMLOptionElement;
                sensorTypeScale.innerText = "Wägezelle";
                sensorTypeScale.value = "2";
                sensorType.append(sensorTypeScale);


                con.append(sensorType);
                thisContainer["sensorType"] = sensorType;

                con.append(document.createElement("br"));


                let changeWhenTypeOfSensor: HTMLElement[] = [];
                let list = ["Pumpen Port ", "Sensor 1 ", "Sensor 2 "];
                for (let t of list) {
                    let labelElement = document.createElement("label");
                    labelElement.innerText = t;
                    changeWhenTypeOfSensor.push(labelElement);
                    con.append(labelElement);

                    let selectElement = document.createElement("select");
                    labelElement.style.display = "none";
                    selectElement.style.display = "none";
                    selectElement.classList.add("input");
                    if (t == "Sensor 1 ") {
                        thisContainer["sensorPin1"] = selectElement;
                    } else if (t == "Sensor 2 ") {
                        thisContainer["sensorPin2"] = selectElement;
                    } else {
                        thisContainer["pumpPin"] = selectElement;
                        labelElement.style.display = "inline";
                        selectElement.style.display = "inline";
                    }

                    let noSel = document.createElement("option") as HTMLOptionElement;
                    noSel.innerText = "Bitte wählen";
                    noSel.value = "-1";
                    noSel.disabled = true;

                    selectElement.append(noSel); //loveyou
                    selectElement.selectedIndex = 0;

                    const pins = [3, 5, 7, 8, 10, 11, 12, 13, 14, 15, 16, 18, 19, 21, 22, 23, 24, 26, 29, 31, 32, 33, 34, 35, 36, 37, 38, 40];
                    for (let pin of pins) {
                        let pinEle = document.createElement("option") as HTMLOptionElement;
                        pinEle.innerText = "" + pin;
                        pinEle.value = "" + pin;
                        selectElement.append(pinEle);
                    }
                    con.append(selectElement);

                    let br = document.createElement("br");
                    con.append(br);
                }

                sensorType.onchange = () => {
                    // 0 => ultrasound; 1 => scale
                    if (sensorType.value == "1") {
                        thisContainer["sensorPin1"].style.display = "inline";
                        thisContainer["sensorPin2"].style.display = "inline";
                        changeWhenTypeOfSensor[1].style.display = "inline";
                        changeWhenTypeOfSensor[2].style.display = "inline";
                        changeWhenTypeOfSensor[1].innerText = "Trigger Pin ";
                        changeWhenTypeOfSensor[2].innerText = "Echo Pin ";
                    } else if (sensorType.value == "2") {
                        thisContainer["sensorPin1"].style.display = "inline";
                        thisContainer["sensorPin2"].style.display = "inline";
                        changeWhenTypeOfSensor[1].style.display = "inline";
                        changeWhenTypeOfSensor[2].style.display = "inline";
                        changeWhenTypeOfSensor[1].innerText = "Clock Pin ";
                        changeWhenTypeOfSensor[2].innerText = "Data Pin ";
                    } else {
                        thisContainer["sensorPin1"].style.display = "none";
                        thisContainer["sensorPin2"].style.display = "none";
                        changeWhenTypeOfSensor[1].style.display = "none";
                        changeWhenTypeOfSensor[2].style.display = "none";
                        changeWhenTypeOfSensor[1].innerText = "Sensor 1 ";
                        changeWhenTypeOfSensor[2].innerText = "Sensor 2 ";
                    }
                };

                let labelElement = document.createElement("label");
                labelElement.innerText = "Gesamtvolumen (ml) ";
                con.append(labelElement);

                let selectElement = document.createElement("select");
                selectElement.classList.add("input");
                const mls = [50, 100, 200, 250, 300, 330, 500, 750, 1000, 1250, 1500, 2000, 2500, 5000, 10000];
                for (let ml of mls) {
                    let pinEle = document.createElement("option") as HTMLOptionElement;
                    pinEle.innerText = "" + ml;
                    pinEle.value = "" + ml;
                    selectElement.append(pinEle);
                    thisContainer["volume"] = selectElement;
                }
                selectElement.selectedIndex = 7;

                con.append(selectElement);

                let br = document.createElement("br");
                con.append(br);

                containerEle.append(con);
                let cast = thisContainer as { container: HTMLDivElement, slot: number, pumpPin: HTMLSelectElement, sensorType: HTMLSelectElement, sensorPin1: HTMLSelectElement, sensorPin2: HTMLSelectElement, volume: HTMLSelectElement };
                containers.push(cast);
                console.log(cast);
            }
        };

        let div1 = document.createElement("div");
        div1.style.marginBottom = "2%";
        modal.addContent(div1);
        let labelElement = document.createElement("label");
        labelElement.innerText = "Anzahl Slots";
        div1.append(labelElement);

        let numberInputElement = document.createElement("input") as HTMLInputElement;
        numberInputElement.type = "number";
        numberInputElement.id = "setup_slots";
        numberInputElement.classList.add("input");
        numberInputElement.style.width = "20%;"
        numberInputElement.value = "0";
        numberInputElement.min = "0";
        numberInputElement.max = "30";
        numberInputElement.onchange = () => {
            onchange();
        };
        div1.append(numberInputElement);

        let divContainers = document.createElement("div");
        divContainers.id = "setup_containers";
        modal.addContent(divContainers);

        let status = document.createElement("p");
        status.style.color = "black";
        status.innerHTML = "Drücke 'Weiter' zum Speichern";
        modal.addContent(status);

        modal.addButton(ButtonType.SUCCESS, "Weiter", () => {
            status.innerHTML = "...";
            status.style.color = "gray";
            if (numberInputElement.valueAsNumber < 0 || numberInputElement.valueAsNumber > 30) {
                numberInputElement.value = "0";
                status.style.color = "black";
                status.innerHTML = "Automatische Änderungen überprüfen!";
                return;
            }

            // Check
            if (numberInputElement.valueAsNumber != containers.length) {
                onchange();
                status.style.color = "black";
                status.innerHTML = "Automatische Änderungen überprüfen!";
                return;
            }

            if (containers.length == 0) {
                status.style.color = "red";
                status.innerHTML = "Es muss mindestens ein Container hinzugefügt werden!";
                return;
            }

            let newContainers: { slot: number, pumpPin: number, sensorPin1: number, sensorPin2: number, volume: number }[] = [];
            let ok = true;
            for (let c of containers) {
                for (let c2 of containers) {
                    if (c.slot == c.slot) continue;

                    let pins = [c.sensorPin1.value, c.sensorPin2.value, c.pumpPin.value, c2.sensorPin1.value, c2.sensorPin2.value, c2.pumpPin.value];

                    let i = 0;
                    for (let pin of pins) {
                        let j = 0;
                        if (pin == "-1") {
                            console.log("Skip ", pin);
                            continue;
                        }

                        for (let pin2 of pins) {
                            // Wenn index derselbe ist, ignorieren
                            if (j == i) {
                                console.log("Index skip ", pin);
                                continue;
                            }

                            if (pin2 == "-1") {
                                console.log("Skip ", pin);
                                continue;
                            }

                            if (pin == pin2) {
                                console.log("Pin same error", pin, pin2, c, c2)
                                ok = false;
                                c.container.classList.add("error");
                                c2.container.classList.add("error");
                                setTimeout(() => {
                                    c.container.classList.remove("error");
                                    c2.container.classList.remove("error");
                                }, 2000);
                                break;
                            }

                            j++;
                        }
                        i++;
                        if (!ok) break;
                    }
                    if (!ok) break;

                    /*console.log(c, c2);
                    console.log(c.sensorPin2.value == c2.sensorPin2.value);
                    if (
                        c.pumpPin.value == c2.pumpPin.value ||
                        (c.sensorType.value != "0" && (
                            (c.sensorPin1.value == c2.sensorPin1.value)
                            || (c.sensorPin2.value == c2.sensorPin2.value)
                            || (c.sensorPin1.value == c2.sensorPin2.value)
                            || (c.sensorPin2.value == c2.sensorPin1.value)))
                    ) {
                        console.log("Check not ok")
                        ok = false;
                        c.container.classList.add("error");
                        c2.container.classList.add("error");
                        setTimeout(() => {
                            c.container.classList.remove("error");
                            c2.container.classList.remove("error");
                        }, 2000);
                        break;
                    }*/
                }
                if (!ok) break;

                if (c.pumpPin.value == "-1" || (c.sensorType.value != "0" && (c.sensorPin1.value == "-1" || c.sensorPin2.value == "-1"))) {
                    console.log("Local check invalid", c);
                    ok = false;
                    c.container.classList.add("error");

                    setTimeout(() => {
                        c.container.classList.remove("error");

                    }, 1000);
                }


                let pins = [c.sensorPin1.value, c.sensorPin2.value, c.pumpPin.value];

                let i = 0;
                for (let pin of pins) {
                    let j = 0;
                    if (pin == "-1") {
                        console.log("Skip ", pin);
                        continue;
                    }
                    for (let pin2 of pins) {
                        // Wenn index derselbe ist, ignorieren
                        if (j == i) {
                            console.log("Index skip ", pin);
                            continue;
                        }

                        if (pin2 == "-1") {
                            console.log("Skip ", pin);
                            continue;
                        }

                        if (pin == pin2) {
                            console.log("Pin same error", pin, pin2, c)
                            ok = false;
                            c.container.classList.add("error");
                            setTimeout(() => {
                                c.container.classList.remove("error");
                            }, 2000);
                            break;
                        }

                        j++;
                    }
                    i++;
                }

                /*if (c.pumpPin.value == c.sensorPin1.value || c.pumpPin.value == c.sensorPin2.value || c.sensorPin1.value == c.sensorPin2.value) {
                    ok = false;
                    c.container.classList.add("error");

                    setTimeout(() => {
                        c.container.classList.remove("error");

                    }, 1000);
                    break;
                }*/

                newContainers.push({
                    slot: c.slot,
                    sensorPin1: parseInt(c.sensorPin1.value),
                    sensorPin2: parseInt(c.sensorPin2.value),
                    pumpPin: parseInt(c.pumpPin.value),
                    volume: parseInt(c.volume.value)
                });
            }
            if (!ok) {
                status.style.color = "red";
                status.innerHTML = "Problem erkannt<br>Bitte überprüfen, ob alle benötigten Felder gesetzt sind<br>und ob Pins nicht mehrfach belegt sind!"
                return;
            }

            // todo Hier konfiguration an Server senden und speichern

            // zurück und hinsenden mittels function die hier in der WebHandler.ts gespeichert wird maybe?

            status.style.color = "green";
            status.innerHTML = "Konfiguration gespeichert!";

            let tareModal = new Modal("setup", "Setup 2/2");

            let container = document.createElement("div");
            tareModal.addContent(container);

            let txt = document.createElement("p");
            txt.innerHTML = `Um das Setup abzuschließen, müssen die Sensoren eingestellt werden.<br>
Bitte zunächst jegliche Behälter von/unter den Sensoren entfernen.<br>Zum fortfahren "Messen"-Schaltfläche berühren.<br>`;
            tareModal.addContent(txt);


            let btn = tareModal.addButton(ButtonType.SUCCESS, "Messen", () => {
                txt.innerHTML = "<strong>Messung läuft...</strong><br><span style='text-decoration: underline'>Gerät nicht berühren!</span><br><div class=\"lds-ellipsis\">\n" +
                    "  <div></div><div></div><div></div><div></div>\n" +
                    "</div>";
                btn.disabled = true;
                btn.innerText = "Bitte warten";
            });
            // todo send messung to server to start

            tareModal.open();
        });

        //await modal.open();

        let setupNumber = document.getElementById("setup_slots") as HTMLInputElement;
        setupNumber.focus();
    }

    public static openPane(pane: Pane): void {
        let mainPanel = document.getElementById("main") as HTMLDivElement;
        let setupPanel = document.getElementById("setup") as HTMLDivElement;
        let menuPanel = document.getElementById("menu") as HTMLDivElement;
        let settingsPanel = document.getElementById("settings") as HTMLDivElement;


        mainPanel.classList.add("hiddenPane");
        setupPanel.classList.add("hiddenPane");
        menuPanel.classList.add("hiddenPane");
        settingsPanel.classList.add("hiddenPane");


        switch (pane) {
            case Pane.MAIN: {
                mainPanel.classList.remove("hiddenPane");
                break;
            }
            case Pane.MENU: {
                menuPanel.classList.remove("hiddenPane");
                break;
            }
            case Pane.SETUP: {
                setupPanel.classList.remove("hiddenPane");
                break;
            }
            case Pane.SETTINGS: {
                settingsPanel.classList.remove("hiddenPane");
                break;
            }
        }

        let title = document.getElementById("title") as HTMLTitleElement;
        title.innerText = pane.toString();
    }
}