package de.duehl.vocabulary.japanese.logic.translation;

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.vocabulary.japanese.data.Vocable;
import de.duehl.vocabulary.japanese.data.Vocabulary;

/**
 * Diese Klasse kümmert sich um die Übersetzung von Deutsch in Japanisch.
 *
 * In den Vokabularien liegen die Vokabeln von Japanisch nach Deutsch vor. Für die Rückrichtung
 * bedarf es etwas Aufwand, möchte man nicht mehrfache Bedeutungen unterschlagen.
 *
 * @version 1.01     2024-08-21
 * @author Christian Dühl
 */

public class GermanToJapaneseTranslation {

    private static final boolean PRINT_MULTIPLE_VOCABLE_GERMAN_TERMS = false;


    /** Die Liste mit den Vokabularien. */
    private final List<Vocabulary> vocabularies;

    /** Das Verzeichnis der zu der deutschen Übersetzung passenden Vokabeln. */
    private final Map<String, List<Vocable>> vocablesByGermanTerms;

    /**
     * Konstruktor.
     *
     * @param vocabularies
     *            Die Liste mit den Vokabularien.
     */
    public GermanToJapaneseTranslation(List<Vocabulary> vocabularies) {
        this.vocabularies = vocabularies;

        vocablesByGermanTerms = new HashMap<>();
        fillHash();
        printMultipleVocableGermanTerms();
    }

    private void fillHash() {
        for (Vocabulary vocabulary : vocabularies) {
            fillHashForVocabulary(vocabulary);
        }
    }

    private void fillHashForVocabulary(Vocabulary vocabulary) {
        for (Vocable vocable : vocabulary.getVocables()) {
            fillHashForVocable(vocable);
        }
    }

    private void fillHashForVocable(Vocable vocable) {
        for (String germanTerm : vocable.getTranslations()) {
            if (!vocablesByGermanTerms.containsKey(germanTerm)) {
                vocablesByGermanTerms.put(germanTerm, new ArrayList<>());
            }
            List<Vocable> list = vocablesByGermanTerms.get(germanTerm);
            if (!list.contains(vocable)) {
                list.add(vocable);
            }
        }
    }

    private void printMultipleVocableGermanTerms() {
        if (PRINT_MULTIPLE_VOCABLE_GERMAN_TERMS) {
            reallyPrintMultipleVocableGermanTerms();
        }
    }


    private void reallyPrintMultipleVocableGermanTerms() {
        System.out.println("Alle Übersetzungen, die zu mehr als einer Vokabel passen:");

        List<String> sortedGermanTerms =
                CollectionsHelper.getSortedMapStringIndices(vocablesByGermanTerms);
        for (String germanTerm : sortedGermanTerms) {
            List<Vocable> vocables = vocablesByGermanTerms.get(germanTerm);
            if (vocables.size() > 1) {
                System.out.print(germanTerm);
                for (Vocable vocable : vocables) {
                    System.out.print(""
                            + " - "
                            + vocable.getKanji()
                            + " "
                            + vocable.getKana()
                            + " "
                            + vocable.getTranslations().get(0)
                            );
                }
                System.out.println();
            }
        }
    }

    /** Gibt zu einem deutschen Begriff die passenden Vokabeln zurück. */
    public List<Vocable> getMatchingVocablesForGermanTerm(String germanTerm) {
        if (vocablesByGermanTerms.containsKey(germanTerm)) {
            return vocablesByGermanTerms.get(germanTerm);
        }
        else {
            throw new RuntimeException("Zum deutschen Begriff '" + germanTerm + "' ist keine "
                    + "zugehörige Vokabel bekannt.");
        }
    }

}
