package de.duehl.vocabulary.japanese.ui.dialog.testing;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JPanel;

import de.duehl.swing.ui.GuiTools;
import de.duehl.swing.ui.components.MultipleElementsPanel;
import de.duehl.swing.ui.components.selections.StringSelection;
import de.duehl.swing.ui.components.selections.tools.SelectionsHelper;
import de.duehl.swing.ui.dialogs.base.ModalDialogBase;
import de.duehl.vocabulary.japanese.common.persistence.Options;
import de.duehl.vocabulary.japanese.data.FumikoDataStructures;
import de.duehl.vocabulary.japanese.data.Vocable;
import de.duehl.vocabulary.japanese.logic.internal.InternalDataRequester;
import de.duehl.vocabulary.japanese.ui.components.VocableViewer;
import de.duehl.vocabulary.japanese.ui.data.FumikoUiObjects;

/**
 * Diese Klasse lässt den Benutzer nach einer falschen Übersetzung,welche nur ein Tippfehler war,
 * eine der möglichen Vokabeln auswählen.
 *
 * @version 1.01     2025-11-20
 * @author Christian Dühl
 */

public class VocableAfterTypingErrorSelectorDialog extends ModalDialogBase {

    /** Die vom Benutzer eingegebene Übersetzung mit Tippfehler. */
    private final String translationByUser;

    /**
     * Die in Frage kommenden Vokabeln, diese passen zu den bei der Übersetzung angezeigten
     * Informationen).
     */
    private final List<Vocable> matchingVocables;

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

    /**
     * Die Vokabel, die der Benutzer ausgewählt hat und die zu seiner tippfehlerbehafteten
     * Übersetzung passt (zumindest glauben wir ihm das).
     */
    private Vocable correctVocable;

    /** Gibt an, ob der Benutzer eine Vokabel ausgesucht hat. */
    private boolean hasUserSelected;

    /**
     * Konstruktor.
     *
     * @param translationByUser
     *            Die vom Benutzer eingegebene Übersetzung mit Tippfehler.
     * @param matchingVocables
     *            Die in Frage kommenden Vokabeln, diese passen zu den bei der Übersetzung
     *            angezeigten Informationen).
     * @param dataStructures
     *            Die Datenstrukturen des Vokabeltrainers.
     * @param uiObjects
     *            Die häufig verwendeten Funktionen der grafischen Oberfläche des Vokabeltrainers.
     * @param parentLocation
     *            Position des Rahmens der Oberfläche, vor der dieser Dialog erzeugt wird.
     */
    public VocableAfterTypingErrorSelectorDialog(String translationByUser,
            List<Vocable> matchingVocables, FumikoDataStructures dataStructures,
            FumikoUiObjects uiObjects, Point parentLocation) {
        super(parentLocation, uiObjects.getProgramImage(),
                "Auswahl der zur vertippten Übersetzung passenden Vokabel");
        this.translationByUser = translationByUser;
        this.matchingVocables = matchingVocables;
        this.dataStructures = dataStructures;

        hasUserSelected = false;

        fillDialog();
    }

    @Override
    protected void populateDialog() {
        add(createTranlationPart(), BorderLayout.NORTH);
        add(GuiTools.createScrollPane(createTitledMatchingVocablesPart()), BorderLayout.CENTER);
    }

    private Component createTranlationPart() {
        StringSelection translationSelection = new StringSelection("Die Übersetzung mit Tippfehler");
        SelectionsHelper.initSelectionAsViewer(translationSelection);
        translationSelection.setText(translationByUser);
        translationSelection.biggerLabelText(5);
        return translationSelection.getPanel();
    }

    private Component createTitledMatchingVocablesPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        GuiTools.createTitledBorder("In Frage kommende Vokabeln", panel);

        panel.add(createMatchingVocablesPart(), BorderLayout.CENTER);

        return panel;
    }

    private Component createMatchingVocablesPart() {
        List<Component> vocableSelectionPanels = createVocableSelectionPanels();
        if (vocableSelectionPanels.size() == 1) {
            return vocableSelectionPanels.get(0);
        }
        else {
            return createMultipleVocableSelectionPanelsDisplay(vocableSelectionPanels);
        }
    }

    private List<Component> createVocableSelectionPanels() {
        List<Component> vocableSelectionPanels = new ArrayList<>();
        for (Vocable vocable : matchingVocables) {
            vocableSelectionPanels.add(createVocableComponent(vocable));
        }
        return vocableSelectionPanels;
    }

    private Component createVocableComponent(Vocable vocable) {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        panel.add(createVocableButton(vocable), BorderLayout.WEST);
        panel.add(createVocablePanel(vocable), BorderLayout.CENTER);

        return panel;
    }

    private Component createMultipleVocableSelectionPanelsDisplay(
            List<Component> vocableSelectionPanels) {
        int numerOfVocables = vocableSelectionPanels.size();
        int numberOfColumns;
        if (numerOfVocables > 4) {
            numberOfColumns = 3;
        }
        else if (numerOfVocables > 2) {
            numberOfColumns = 2;
        }
        else {
            numberOfColumns = 1;
        }
        JPanel panel = new MultipleElementsPanel<Component>(vocableSelectionPanels, numberOfColumns,
                1);
        return panel;
    }

    private Component createVocableButton(Vocable vocable) {
        String text = "auswählen";
        /*
        String text = ""
                + "<html><span style=\"writing-mode: vertical-lr;\">"
                + "auswählen"
                + "</span></html>";
         * das beachtet er leider nicht.
         */
        JButton button = new JButton(text);
        button.addActionListener(e -> userSelectsVocable(vocable));
        //button.setUI(new VerticalButtonUI(90)); // Das sieht leider blöd aus, der Button ist
        // nicht mehr als solcher zu erkennen.
        return button;
    }

    private Component createVocablePanel(Vocable vocable) {
        Options options = dataStructures.getOptions();
        InternalDataRequester requester = dataStructures.getInternalDataRequester();
        VocableViewer viewer = new VocableViewer(options);
        viewer.showVocable(vocable, requester.getInternalDataForVocable(vocable));
        return viewer.getPanel();
    }

    private void userSelectsVocable(Vocable vocable) {
        hasUserSelected = true;
        correctVocable = vocable;
        closeDialog();
    }

    /**
     * Getter für die Vokabel, die der Benutzer ausgewählt hat und die zu seiner
     * tippfehlerbehafteten Übersetzung passt (zumindest glauben wir ihm das).
     */
    public Vocable getCorrectVocable() {
        return correctVocable;
    }

    /** Gibt an, ob der Benutzer eine Vokabel ausgesucht hat. */
    public boolean hasUserSelected() {
        return hasUserSelected;
    }

}
