package de.duehl.vocabulary.japanese.grammar.find;

import java.util.ArrayList;
import java.util.List;

import de.duehl.vocabulary.japanese.data.Vocable;
import de.duehl.vocabulary.japanese.data.Vocabulary;

/**
 * Diese Klasse findet zu einer Vokabel passende andere Vokabeln mit zugehöriger Form.
 *
 * Dies geschieht über die in der Bemerkung in japanischen Anführungszeichen aufgeführten
 * Grundformen.
 *
 * @version 1.01     2025-11-26
 * @author Christian Dühl
 */

public class RelatedVocablesFinder {

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

    /** Die Vokabel, zu der zugehörige Vokabeln gleicher Art gesucht werden. */
    private final Vocable vocable;

    /** Das Objekt das prüfen kann, ob eine Vokabel von der gleichen Art ist. */
    private final RelatedVocableDeterminer relatedVocableDeterminer;

    /** Die Liste der zugehörigen Vokabeln. */
    private List<Vocable> relatedVocables;

    /**
     * Konstruktor.
     *
     * @param vocabularies
     *            Die Liste mit den bekannten Vokabularien.
     * @param vocable
     *            Die Vokabel, zu der zugehörige Vokabeln gleicher Art gesucht werden.
     * @param relatedVocableDeterminer
     *            Das Objekt das prüfen kann, ob eine Vokabel von der gleichen Art ist.
     */
    public RelatedVocablesFinder(List<Vocabulary> vocabularies, Vocable vocable,
            RelatedVocableDeterminer relatedVocableDeterminer) {
        this.vocabularies = vocabularies;
        this.vocable = vocable;
        this.relatedVocableDeterminer = relatedVocableDeterminer;

        if (!relatedVocableDeterminer.isRelatedVocable(vocable)) {
            throw new RuntimeException("Die Vokabel erfüllt selbst nicht die verlangte Bedingung.");
        }
    }

    /** Sucht nach den zugehörigen Vokabeln. */
    public void find() {
        relatedVocables = new ArrayList<>();
        relatedVocables.add(vocable);

        String kanji = vocable.getKanji();
        String romaji = vocable.getRomaji();

        String kanaWithQuotes = vocable.getKanaInJapaneseQuotes();
        String kanjiWithQuotes = vocable.getKanjiInJapaneseQuotes();

        List<Vocable> otherVerbs = collectOtherVocables(vocable);

        for (Vocable otherVerb : otherVerbs) {
            String bemerkung = otherVerb.getComment();
            boolean related = false;
            if (kanji.isBlank()) {
                related = bemerkung.contains(kanaWithQuotes)
                        && bemerkung.contains(romaji);
            }
            else {
                related = bemerkung.contains(kanjiWithQuotes)
                        && bemerkung.contains(kanaWithQuotes)
                        && bemerkung.contains(romaji);
            }

            if (related) {
                relatedVocables.add(otherVerb);
            }
        }
    }

    private List<Vocable> collectOtherVocables(Vocable vocable) {
        List<Vocable> otherVocables = new ArrayList<>();

        for (Vocabulary vocabulary : vocabularies) {
            for (Vocable anOtherVocable : vocabulary.getVocables()) {
                if (!anOtherVocable.equals(vocable)
                        && relatedVocableDeterminer.isRelatedVocable(anOtherVocable)) {
                    otherVocables.add(anOtherVocable);
                }
            }
        }

        return otherVocables;
    }

    /** Getter für die Liste der zugehörigen Vokabeln. */
    public List<Vocable> getRelatedVocables() {
        return relatedVocables;
    }

}
