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

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import de.duehl.vocabulary.japanese.data.symbol.Kanji;

/**
 * Diese Klasse sortiert eine Liste von nach bestimmten Suchkriterien gefundenen Kanji anhand
 * eines Suchbegriffs nach Relevanz.
 *
 * @version 1.01     2024-11-20
 * @author Christian Dühl
 */

public class KanjiListSorter {

    /**
     * Die Liste der gefundenen Kanji, die den Suchkriterien entsprechen. Diese Liste wird hier
     * sortiert.
     */
    private final List<Kanji> kanjiList;

    /** Der Suchbegriff, nach dem die gefundenen Kanji nach Relevanz sortiert werden sollen. */
    private final String search;

    /**
     * Das Verzeichnis der Bewertungen der Relevanz nach den Kanji.
     *
     * Eine höhere Relevanz drückt sich in einer kleineren Zahl aus.
     */
    private Map<Kanji, Integer> relevanceWeighting;

    /**
     * Konstruktor.
     *
     * @param kanjiList
     *            Die Liste der gefundenen Kanji, die den Suchkriterien entsprechen. Diese Liste
     *            wird hier sortiert.
     * @param search
     *            Der Suchbegriff, nach dem die gefundenen Kanji nach Relevanz sortiert werden
     *            sollen.
     */
    public KanjiListSorter(List<Kanji> kanjiList, String search) {
        this.kanjiList = kanjiList;
        this.search = search;
    }

    /** Führt die Sortierung durch. */
    public void sort() {
        if (kanjiList.size() > 1 && !search.isBlank()) {
            reallySort();
        }
    }

    private void reallySort() {
        createRelevanceWeighting();
        sortByRelevanceWeighting();
    }

    private void createRelevanceWeighting() {
        relevanceWeighting = new HashMap<>();
        for (Kanji kanji : kanjiList) {
            int weighting = calculateRelevanceWeighting(kanji);
            relevanceWeighting.put(kanji, weighting);
        }
    }

    private int calculateRelevanceWeighting(Kanji kanji) {
        KanjiRelevanceWeightingCalculator calculator =
                new KanjiRelevanceWeightingCalculator(kanji, search);
        calculator.calculate();
        return calculator.getWeighting();
    }

    private void sortByRelevanceWeighting() {
        Collections.sort(kanjiList, new Comparator<Kanji>() {
            @Override
            public int compare(Kanji k1, Kanji k2) {
                int weighting1 = relevanceWeighting.get(k1);
                int weighting2 = relevanceWeighting.get(k2);
                return weighting1 - weighting2; // kleiner gewinnt
            }
        });
    }

}
