package de.duehl.vocabulary.japanese.tools;

import java.util.Collections;
import java.util.List;

import de.duehl.basics.collections.CollectionsHelper;
import de.duehl.swing.ui.GuiTools;
import de.duehl.vocabulary.japanese.common.data.VocablesShuffleType;
import de.duehl.vocabulary.japanese.common.data.VocablesSubsetSelectionType;
import de.duehl.vocabulary.japanese.common.persistence.Options;
import de.duehl.vocabulary.japanese.data.FumikoDataStructures;
import de.duehl.vocabulary.japanese.data.Vocable;

/**
 * Diese Klasse erstellte eine Teilmenge von Vokabeln auf die gewünschte Weise.
 *
 * @version 1.01     2025-11-20
 * @author Christian Dühl
 */

public class VocableSubsetCreator {

    /** Die Datenstrukturen des Vokabeltrainers. */
    private final FumikoDataStructures dataStructures;

    /** Die Liste mit allen abzufragenden Vokabeln. */
    private final List<Vocable> allVocables;

    /** Die Art wie die Teilmenge ausgewählt werden soll. */
    private final VocablesSubsetSelectionType type;

    /** Die Anzahl der gewünschten Vokabeln in der erzeugten Teilmenge (ggf. reduziert). */
    private final int numberOfWantedVocables;

    /** Die doppelte Anzahl der gewünschten Vokabeln in der erzeugten Teilmenge (ggf. reduziert). */
    private final int numberOfWantedVocablesTwice;

    /** Die Teilmenge der Vokabeln, die hier erzeugt wird. */
    private List<Vocable> subset;

    /**
     * Konstruktor.
     *
     * @param allVocables
     *            Die Liste mit allen abzufragenden Vokabeln.
     * @param numberOfWantedVocables
     *            Die Anzahl der gewünschten Vokabeln in der erzeugten Teilmenge.
     * @param dataStructures
     *            Die Datenstrukturen des Vokabeltrainers.
     */
    public VocableSubsetCreator(List<Vocable> allVocables, int numberOfWantedVocables,
            FumikoDataStructures dataStructuress) {
        this.allVocables = CollectionsHelper.copyList(allVocables);

        Options options = dataStructuress.getOptions();
        this.type = options.getVocablesSubsetSelectionType();

        this.numberOfWantedVocables = Math.min(numberOfWantedVocables, allVocables.size());
        numberOfWantedVocablesTwice = Math.min(numberOfWantedVocables * 2, allVocables.size());

        this.dataStructures = dataStructuress;
    }

    /** Erzeugt die Teilmenge. */
    public void create() {
        switch (type) {
            case PURE_RANDOM:
                createPureRandomSubset();
                break;
            case RANDOM_AND_LAST_ANSWER_SUCCESS:
                createRandomAndLastAnswerSuccessSubset();
                break;
            case RANDOM_AND_FIRST_SEEN_DATE:
                createRandomAndFirstSeenSubset();
                break;
            case RANDOM_AND_LAST_CORRECT_TEST_DATE:
                createRandomAndLastCorrectTestDateSubset();
                break;
            case RANDOM_AND_MIX:
                createRandomAndMixSubset();
                break;
            default:
                createUnknown();
                break;
        }
    }

    private void createPureRandomSubset() {
        Collections.shuffle(allVocables);
        subset = CollectionsHelper.sublist(allVocables, 0, numberOfWantedVocables);
    }

    private void createRandomAndLastAnswerSuccessSubset() {
        create(VocablesShuffleType.LAST_ANSWERS_SUCCESS);
    }

    private void createRandomAndFirstSeenSubset() {
        create(VocablesShuffleType.FIRST_SEEN_DATE);
    }

    private void createRandomAndLastCorrectTestDateSubset() {
        create(VocablesShuffleType.LAST_CORRECT_TEST_DATE);
    }

    private void createRandomAndMixSubset() {
        create(VocablesShuffleType.MIX);
    }

    private void create(VocablesShuffleType shuffleType) {
        presortAllVocables(shuffleType);
        createSubsetFromPresortedAllVocables();
    }

    private void presortAllVocables(VocablesShuffleType shuffleType) {
        VocableListShuffler shuffler = new VocableListShuffler(allVocables, shuffleType,
                dataStructures);
        shuffler.shuffle();
        allVocables.clear();
        allVocables.addAll(shuffler.getVocables());
    }

    private void createSubsetFromPresortedAllVocables() {
        subset = CollectionsHelper.sublist(allVocables, 0, numberOfWantedVocablesTwice);
        Collections.shuffle(subset);
        subset = CollectionsHelper.sublist(subset, 0, numberOfWantedVocables);
    }

    private void createUnknown() {
        GuiTools.informUser("Unbekannte Art eine Teilmenge zu erezugen", ""
                + "Die Art '" + type + "' die Teilmenge zu erezugen ist unbekannt.\n\n"
                + "Daher wird die Teilmenge rein zufällig ermittelt.");
        createPureRandomSubset();
    }

    /** Getter für die Teilmenge der Vokabeln, die hier erzeugt wird. */
    public List<Vocable> getSubset() {
        return subset;
    }

}
