/*
 * for testing:
 * aktuellesProblem = {"artikel": "der/die/das/die", "artikelTyp": 0, "nomen": "Messer/Messer/n", "adjektiv": "braun", "kasus": 1, "genus": "n", "nummer": 0, "modell": dingeAkkModell.next().value};
 */
/*
 * Gibt random integer 0 <= resultat < max
 */
function getRandomInt(max) {
  return Math.floor(Math.random() * max);
}

function mischen(arr) {
    var n = arr.length;
    for (var i = 0; i < n - 1; i++) {
        j = i + getRandomInt(n - i);
        var temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

function erstEntfernen(arr) {
    let wert = arr.splice(0, 1)[0];
    return wert;
}

function wertErhalten(arr) {
    return arr[0];
}

function add(arr,value){
    arr.push(value);
}

const NIVEAU_A2 = 0
const NIVEAU_B1 = 1

const NEU = 0
const RICHTIG = 1
const FALSCH1 = 2
const FALSCH2 = 3
const FALSCH3 = 4

let wörteStatus = [
    [
        [], // 0 neu
        [], // 1 - richtig
        [], // 2 - einmal falsch
        [], // 3 - zweimal falsch
        []  // 4 - 3+ mal falsch
    ],
    [
        [], // 0 neu
        [], // 1 - richtig
        [], // 2 - einmal falsch
        [], // 3 - zweimal falsch
        []  // 4 - 3+ mal falsch
    ],
];

let aktuellNiveau = NIVEAU_A2;

function nimmStatus(niveau, kategorie) {
    let wörterString = localStorage.getItem(niveau + "_" + kategorie);
    if (wörterString != null && wörterString != "") {
        wörteStatus[niveau][kategorie] = wörterString.split("\n");
    }
}

function setzStatus(niveau, kategorie) {
    let str = wörteStatus[niveau][kategorie].join("\n");
    localStorage.setItem(niveau + "_" + kategorie, str);
}

const NIVEAU = 0;
const ARTIKEL = 1;
const SUBSTANTIV = 2;
const PLURAL = 3;
const BEDEUTUNG = 4;

let bewertung = 0;
let nFrage = 0;
let nVersuch = 0;

let aktuellesProblem;

function wählOption(arr) {
    let n = getRandomInt(arr.length);
    return arr[n];
}

/*
 * Für Randomisierung, wir mischen
 * vor wir aus der List nehmen
 */
function nehmenAus(aList) {
    mischen(aList);
    return [aList, aList[0]];
}

/*
 * Das problem ist gleich als die Lösung.
 */
function problemErstellen() {
    let sourceList;
    let sourcePosition;
    let wort;
    /*
     * Repeat a past wrong answer?
     */
    let wiederholen = (getRandomInt(4) == 0);
    let status = wörteStatus[aktuellNiveau];

    /* aber nur wenn es lohnt sich */
    if (wiederholen && (
        status[RICHTIG].length + status[FALSCH1].length +
        status[FALSCH2].length + status[FALSCH3].length) < 5)
    {
        wiederholen = false;
    }

    if (wiederholen) {
        // console.log("wiederholen");
        if (status[FALSCH3].length > 0) {
            [sourceList, wort] = nehmenAus(status[FALSCH3]);
            // console.log("got repeat", wort, "from wrong3");
        } else if (status[FALSCH2].length > 0) {
            [sourceList, wort] = nehmenAus(status[FALSCH2]);
            // console.log("got repeat", wort, "from wrong2");
        } else if (status[FALSCH1].length > 0) {
            [sourceList, wort] = nehmenAus(status[FALSCH1]);
            // console.log("got repeat", wort, "from wrong1");
        } else if (status[RICHTIG].length > 0) {
            [sourceList, wort] = nehmenAus(status[RICHTIG]);
            // console.log("got repeat", wort, "from correct");
        }
    } else {
        if (status[NEU].length > 0) {
            [sourceList, wort] = nehmenAus(status[NEU]);
            // console.log("got", wort, "from new words");
        } else if (status[FALSCH3].length > 0) {
            [sourceList, wort] = nehmenAus(status[FALSCH3]);
            // console.log("got", wort, "from wrong3");
        } else if (status[FALSCH2].length > 0) {
            [sourceList, wort] = nehmenAus(status[FALSCH2]);
            // console.log("got", wort, "from wrong2");
        } else if (status[FALSCH1].length > 0) {
            [sourceList, wort] = nehmenAus(status[FALSCH1]);
            // console.log("got", wort, "from wrong1");
        } else if (status[RICHTIG].length > 0) {
            [sourceList, wort] = nehmenAus(status[RICHTIG]);
            // console.log("got", wort, "from correct");
        }
    }

    let teile = wort.split(";");
    return {
        "artikel": teile[0],
        "substantiv": teile[1],
        "plural": teile[2],
        "uebersetzung": teile[3],
        "sourceList": sourceList
    }
}

function problemAnzeigen(problem) {
    insertHTML(problem.substantiv, "substantivText");
    if (problem.plural != "") {
        setClass("pluralText", "sichtbar");
        setClass("keinPlural", "unsichtbar");
    } else {
        setClass("pluralText", "unsichtbar");
        setClass("keinPlural", "sichtabar");
    }
    insertHTML(problem.uebersetzung, "úbersetzung");
}

function canonical(str) {
    str = str.trim().replaceAll(".", " ").replaceAll(/\s+/g, " ")
    str = str.replaceAll("ß", "ss");
    str = str.replaceAll("ä", "ae").replaceAll("ü", "ue").replaceAll("ö", "oe");
    str = str.replaceAll("Ä", "Ae").replaceAll("Ü", "Ue").replaceAll("Ö", "Oe");
    return str;
}

function fehlerWert(id, isOK) {
    let n = 0;
    if (isOK) {
        setClass(id, "richtig");
    } else {
        setClass(id, "falsch");
        n = 1;
    }
    return n;
}

function auswerten(evt) {

    function multiAuswerten(richtig, antwort) {
        let canon = canonical(antwort);
        let teile = richtig.split("/");
        return teile.some((element) => (canonical(element) == canon));
    }

    evt.preventDefault();
    let artikelOK = multiAuswerten(aktuellesProblem.artikel,
                                   document.getElementById("artikelInput").value);
    let pluralOK = multiAuswerten(aktuellesProblem.plural,
                                  document.getElementById("pluralInput").value);;
    let nFehler = 0;
    let feedbackStr = "";

    nFehler += fehlerWert("artikelInput", artikelOK);
    nFehler += fehlerWert("pluralInput", pluralOK);

    if (nFehler == 0) {
        let congrats = ["Richtig!", "Gut gemacht!", "Ach, wie gut!", "Exzellent!",
            "Ausgezeichnet!"];
        if (nVersuch == 0) {
            feedbackStr += `${congrats[getRandomInt(congrats.length)]}`;
        } else {
            feedbackStr += `<span class="normal">Richtig.</span>`;
        }

        if (nVersuch == 0) {
            bewertung += 1;
        } else {
            bewertung += 0.5;
        }

        insertHTML(euroFormat(bewertung), "korrect");
        insertHTML(nFrage, "total");
        insertHTML(feedbackStr, "feedback");

        document.getElementById("überprüfen").disabled = true;

        let entfernt = erstEntfernen(aktuellesProblem.sourceList);
        // console.log("entfernt", entfernt);

        add(wörteStatus[aktuellNiveau][Math.min(nVersuch + 1, FALSCH3)], entfernt);

    } else {
        if (nVersuch == 2) {
            feedbackStr = `Lösung: ${aktuellesProblem.artikel} ${aktuellesProblem.substantiv}`;
            if (aktuellesProblem.plural != "") {
                feedbackStr += `; die ${aktuellesProblem.plural}`
            }
            document.getElementById("überprüfen").disabled = true;

            let entfernt = erstEntfernen(aktuellesProblem.sourceList);
            // console.log("entfernt", entfernt);
            // console.log("Hinzugefügt zu wrong3")
            add(wörteStatus[aktuellNiveau][FALSCH3], entfernt);
        } else {
            feedbackStr = "Versuchen Sie wieder, bitte.";
            nVersuch++;
        }
        insertHTML(feedbackStr, "feedback");
    }

}

function insertHTML(text, id) {
    document.getElementById(id).innerHTML = text;
}

function euroFormat(n) {
    let ganzeZahl = Math.floor(n);
    let fraktion = n - ganzeZahl;
    if (fraktion == 0) {
        return n.toString();
    } else {
        return n.toString().replace('.', ',');
    }
}

function setClass(id, className) {
    document.getElementById(id).className = className;
}

function fehlerWert(id, isOK) {
    let n = 0;
    if (isOK) {
        setClass(id, "richtig");
    } else {
        setClass(id, "falsch");
        n = 1;
    }
    return n;
}

function neuesProblem(evt) {
    if (evt != null) {
        evt.preventDefault();
    }
    nVersuch = 0;
    nFrage++;
    aktuellesProblem = problemErstellen();
    insertHTML('\u00a0', "substantivText");

    document.getElementById("artikelInput").value = "";
    document.getElementById("pluralInput").value = "";
    setClass("artikelInput", "keinAntwort");
    setClass("pluralInput", "keinAntwort");

    problemAnzeigen(aktuellesProblem);

    insertHTML("\u00a0", "feedback");
    document.getElementById("überprüfen").disabled = false;
}

function wählNiveau(evt) {
    if (evt.target.id == 'A2') {
        aktuellNiveau = NIVEAU_A2;
    } else if (evt.target.id == 'B1') {
        aktuellNiveau = NIVEAU_B1;
    }
}

function statusSpeichern(evt) {
    evt.preventDefault(); // triggers a dialog
    for (let niveau = NIVEAU_A2; niveau <= NIVEAU_B1; niveau++) {
        for (let kategorie = NEU; kategorie <= FALSCH3; kategorie++) {
            setzStatus(niveau, kategorie);
        }
    }
    alert("Status gespeichert");
}

function setup() {
    // Immer setzen „neu“ Liste...
    for (let niveau = NIVEAU_A2; niveau <= NIVEAU_B1; niveau++) {
        // console.log(niveau, a2_b1_wörter[niveau].length);
        wörteStatus[niveau][NEU] = a2_b1_wörter[niveau].slice();
    }
    // console.log("----");
    // Dann wiederherstellen aus localStorage...
    for (let niveau = NIVEAU_A2; niveau <= NIVEAU_B1; niveau++) {
        for (let kategorie = NEU; kategorie <= FALSCH3; kategorie++) {
            nimmStatus(niveau, kategorie);
            console.log("niveau", niveau, "kategorie", kategorie, wörteStatus[niveau][kategorie].length);
        }
    }

    document.getElementById("A2").addEventListener("change", wählNiveau);
    document.getElementById("B1").addEventListener("change", wählNiveau);

    neuesProblem(null);
    document.getElementById("überprüfen").addEventListener("click", auswerten);
    document.getElementById("weiter").addEventListener("click", neuesProblem);

    addEventListener("beforeunload", statusSpeichern);
}

function reset() {
    localStorage.clear();
    for (let niveau = NIVEAU_A2; niveau <= NIVEAU_B1; niveau++) {
        for (let kategorie = NEU; kategorie <= FALSCH3; kategorie++) {
            wörteStatus[niveau][kategorie] = [];
        }
    }
}
