package de.duehl.vocabulary.japanese.logic.symbol.kanji.set;

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

import de.duehl.basics.collections.CollectionsHelper;
import de.duehl.basics.text.Text;
import de.duehl.vocabulary.japanese.data.KanjiSet;
import de.duehl.vocabulary.japanese.data.symbol.Kanji;

/**
 * Diese Klasse prüft die Kanji-Mengen auf Integrität.
 *
 * @version 1.01     2026-03-18
 * @author Christian Dühl
 */

public class KanjiSetsChecker {

    /** Die Liste der benutzerdefinierten Kanji-Mengen. */
    private List<KanjiSet> kanjiSets;

    /** Die bei der Überprüfung aufgetretenen Warnungen. */
    private List<String> warningStrings;

    /**
     * Konstruktor.
     *
     * @param kanjiSets
     *            Die Liste der benutzerdefinierten Kanji-Mengen.
     */
    public KanjiSetsChecker(List<KanjiSet> kanjiSets) {
        this.kanjiSets = kanjiSets;
    }

    /** Führt die Überprüfung durch. */
    public void check() {
        warningStrings = new ArrayList<>();

        Map<String, List<KanjiSet>> kanjiSetsByGroup = createKanjiSetsByGroup();

        for (String group : CollectionsHelper.getSortedMapStringIndices(kanjiSetsByGroup)) {
            List<KanjiSet> groupList = kanjiSetsByGroup.get(group);
            checkIfKanjiAreInMultipleKanjiSetsOfSameGroup(groupList);
        }
    }

    private Map<String, List<KanjiSet>> createKanjiSetsByGroup() {
        Map<String, List<KanjiSet>> kanjiSetsByGroup = new HashMap<>();

        for (KanjiSet kanjiSet : kanjiSets) {
            String group = kanjiSet.getGroup();
            if (!kanjiSetsByGroup.containsKey(group)) {
                kanjiSetsByGroup.put(group, new ArrayList<>());
            }
            List<KanjiSet> groupList = kanjiSetsByGroup.get(group);
            groupList.add(kanjiSet);
        }

        return kanjiSetsByGroup;
    }

    private void checkIfKanjiAreInMultipleKanjiSetsOfSameGroup(List<KanjiSet> groupList) {
        Map<Kanji, List<String>> namesByKanji = createNamesByKanji(groupList);

        for (Kanji kanji : namesByKanji.keySet()) {
            List<String> namesList = namesByKanji.get(kanji);
            if (namesList.size() > 1) {
                List<String> warnings = new ArrayList<>();
                warnings.add("Das Kanji 「" + kanji.getCharacter() + "」 ist in mehr als einer "
                        + "Kanji-Menge der gleichen Gruppe enthalten:");
                for (String name : namesList) {
                    warnings.add("    in Kanji-Menge '" + name + "'");
                }
                String warningsString = Text.joinWithLineBreak(warnings);
                warningStrings.add(warningsString);
            }
        }
    }

    private Map<Kanji, List<String>> createNamesByKanji(List<KanjiSet> groupList) {
        Map<Kanji, List<String>> namesByKanji = new HashMap<>();

        for (KanjiSet kanjiSet : groupList) {
            for (Kanji kanji : kanjiSet.getSet()) {
                if (!namesByKanji.containsKey(kanji)) {
                    namesByKanji.put(kanji, new ArrayList<>());
                }
                List<String> namesList = namesByKanji.get(kanji);
                namesList.add(kanjiSet.getName());
            }
        }

        return namesByKanji;
    }

    /** Getter für die bei der Überprüfung aufgetretenen Warnungen. */
    public List<String> getWarningStrings() {
        return warningStrings;
    }

}
