package de.duehl.vocabulary.japanese.startup.logic.steps;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import de.duehl.basics.datetime.time.watch.StopWatch;
import de.duehl.basics.io.FileHelper;
import de.duehl.basics.text.NumberString;
import de.duehl.vocabulary.japanese.common.data.InternalAdditionalVocableData;
import de.duehl.vocabulary.japanese.common.persistence.Options;
import de.duehl.vocabulary.japanese.startup.ui.data.SplashScreenable;

import static de.duehl.vocabulary.japanese.startup.logic.StartupLoader.INTERNAL_VARIABLE_DATA_EXTENSION;
import static de.duehl.vocabulary.japanese.startup.logic.StartupLoader.INTERNAL_DATA_DIRECTORY;;

/**
 * Diese Klasse steht für den Schritt zum Einlesen der internen Daten zu den Vokabeln beim Startup
 * des Vokabeltrainers.
 *
 * @version 1.01     2025-11-23
 * @author Christian Dühl
 */

public class Step04ReadInternalVocableData extends StartupStep {

    /** Das Verzeichnis der internen Daten zu einer Vokabel nach ihrem Schlüssel. */
    private Map<String, InternalAdditionalVocableData> key2InternalDataMap;

    /** Die Liste aller Schlüssel der eingelesenen internen Daten. */
    private List<String> allKeysFromReadInternalData;

    /**
     * Konstruktor.
     *
     * @param step
     *            Der Schritt der durchgeführt wird.
     * @param options
     *            Die Programmoptionen.
     * @param splashScreen
     *            Die grafische Oberfläche beim Start in der die Meldungen angezeigt werden.
     * @param watch
     *            Misst die Laufzeit des gesamten Startups.
     */
    public Step04ReadInternalVocableData(String step, Options options,
            SplashScreenable splashScreen, StopWatch watch) {
        super(step, options, splashScreen, watch);
    }

    /** Führt den eigentlichen Inhalt des Schritts aus. */
    @Override
    protected void runInternalStep() {
        appendMessage("Lese interne benutzerabhängige Daten zu allen Vokabeln ...");
        FileHelper.createDirectoryIfNotExists(INTERNAL_DATA_DIRECTORY);

        List<String> internalFiles = FileHelper.findFilesInMainDirectoryNio2WithExtensions(
                INTERNAL_DATA_DIRECTORY, INTERNAL_VARIABLE_DATA_EXTENSION);
        appendMessage(NumberString.taupu(internalFiles.size()) + " interne Datensätze gefunden.");
        appendMessage("Lese interne Datensätze ein ...");

        List<InternalAdditionalVocableData> internalAdditionalVocableDatas = new ArrayList<>();
        for (String filename : internalFiles) {
            InternalAdditionalVocableData data = InternalAdditionalVocableData.load(filename);
            internalAdditionalVocableDatas.add(data);
        }
        appendMessage(NumberString.taupu(internalAdditionalVocableDatas.size())
                + " interne Datensätze eingelesen.");

        key2InternalDataMap = new HashMap<>();
        allKeysFromReadInternalData = new ArrayList<>();
        for (InternalAdditionalVocableData data : internalAdditionalVocableDatas) {
            String key = data.getKey();
            if (key2InternalDataMap.containsKey(key) || allKeysFromReadInternalData.contains(key)) {
                throw new RuntimeException("Der Schlüssel '" + key + "' kommt mehrfach vor!");
            }

            key2InternalDataMap.put(key, data);
            allKeysFromReadInternalData.add(key);
        }
        appendMessage("Verzeichnis mit " + NumberString.taupu(key2InternalDataMap.size())
                + " Verweisen von Schlüssel auf interne Datensätze aufgebaut.");
    }

    /** Getter für das Verzeichnis der internen Daten zu einer Vokabel nach ihrem Schlüssel. */
    public Map<String, InternalAdditionalVocableData> getKey2InternalDataMap() {
        return key2InternalDataMap;
    }

    /** Getter für die Liste aller Schlüssel der eingelesenen internen Daten. */
    public List<String> getAllKeysFromReadInternalData() {
        return allKeysFromReadInternalData;
    }

}
