package de.duehl.vocabulary.japanese.ui.dialog.kana.katakanatest.components;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Point;

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

import de.duehl.swing.ui.components.selections.StringSelection;
import de.duehl.swing.ui.components.selections.tools.SelectionsHelper;
import de.duehl.swing.ui.layout.VerticalLayout;
import de.duehl.vocabulary.japanese.common.data.InternalAdditionalKanaData;
import de.duehl.vocabulary.japanese.data.FumikoDataStructures;
import de.duehl.vocabulary.japanese.data.symbol.Katakana;
import de.duehl.vocabulary.japanese.logic.symbol.kana.internal.InternalKanaDataRequester;
import de.duehl.vocabulary.japanese.ui.data.FumikoUiObjects;
import de.duehl.vocabulary.japanese.ui.dialog.kanji.stroke.KanjiStrokesUiTools;

/**
 * Diese Klasse stellt ein einzelnes Katakana Panel dar.
 *
 * Gezeigt werden Das Zeichen selbst, die deutsche Bedeutung, die ON-Lesungen und die kun-Lesungen.
 *
 * @version 1.01     2026-08-21
 * @author Christian Dühl
 */

public class KatakanaPanel {

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

    /** Die häufig verwendeten Funktionen der grafischen Oberfläche des Vokabeltrainers. */
    private final FumikoUiObjects uiObjects;

    /** Das Katakana als UTF-8-Zeichen. */
    private String katakanaCharacter;

    /** Die Position des aufrufenden Dialogs. */
    private Point parentLocation;

    /** Das Label auf dem das Katakana dargestellt wird. */
    private final KatakanaLabel katakanaLabel;

    /** Gibt an, ob auch die internen Daten zum Katakana angezeigt werden sollen. */
    private boolean showInternalKatakanaData;

    /**
     * Gibt an, ob das Zeichen auch nochmal in einem Viewer angezeigt werden soll, damit es
     * heraus kopiert werden kann.
     */
    private boolean showKatakanaAsViewerToo;

    /** Der Panel auf dem das Katakana dargestellt wird. */
    private final JPanel panel;

    private final StringSelection katakanaAsCharacterSeletion;
    private final StringSelection hepburnSelection;
    private final StringSelection subTypeSelection;

    private final StringSelection testCountSelection;
    private final StringSelection correctTestCountSelection;
    private final StringSelection lastTestDatetSelection;
    private final StringSelection lastCorrectTestDateSelection;
    private final StringSelection lastTenTestResultsSelection;

    private final JButton showKatakanaStrokesButton;

    /**
     * Konstruktor.
     *
     * @param dataStructures
     *            Die Datenstrukturen des Vokabeltrainers.
     * @param uiObjects
     *            Die häufig verwendeten Funktionen der grafischen Oberfläche des Vokabeltrainers.
     */
    public KatakanaPanel(FumikoDataStructures dataStructures, FumikoUiObjects uiObjects) {
        this.dataStructures = dataStructures;
        this.uiObjects = uiObjects;

        katakanaLabel = new KatakanaLabel();
        katakanaLabel.setBiggerFontSize(200); // Default: 400

        showInternalKatakanaData = false;
        showKatakanaAsViewerToo = false;


        panel = new JPanel();

        katakanaAsCharacterSeletion = new StringSelection("Das Katakana (noch einmal zum rauskopieren)");
        hepburnSelection = new StringSelection("Hepburn-Darstellung");
        subTypeSelection = new StringSelection("Unterart");

        testCountSelection = new StringSelection("Anzahl Test");
        correctTestCountSelection = new StringSelection("Anzahl erfolgreicher Test");
        lastTestDatetSelection = new StringSelection("zuletzt getestet am");
        lastCorrectTestDateSelection = new StringSelection("zuletzt erfolgreich getestet am");
        lastTenTestResultsSelection = new StringSelection("Erfolg der letzten Tests");

        showKatakanaStrokesButton = new JButton("Zeige die Strichfolge dieses Katakana an");

        init();
    }

    private void init() {
        initSelections();
        initButtons();
    }

    private void initSelections() {
        initAssetFocusableViewer(katakanaAsCharacterSeletion);
        initAssetFocusableViewer(katakanaAsCharacterSeletion);
        initAssetFocusableViewer(hepburnSelection);
        initAssetFocusableViewer(subTypeSelection);

        initAssetFocusableViewer(testCountSelection);
        initAssetFocusableViewer(correctTestCountSelection);
        initAssetFocusableViewer(lastTestDatetSelection);
        initAssetFocusableViewer(lastCorrectTestDateSelection);
        initAssetFocusableViewer(lastTenTestResultsSelection);
    }

    private void initAssetFocusableViewer(StringSelection selection) {
        SelectionsHelper.initSelectionAsViewer(selection);
        selection.setFocusable(true);
    }

    private void initButtons() {
        showKatakanaStrokesButton.addActionListener(e -> showKatakanaStrokes());
    }

    private void showKatakanaStrokes() {
        KanjiStrokesUiTools.showKanjiStrokes(katakanaCharacter, dataStructures.getKanjiStrokes(),
                panel, parentLocation, uiObjects.getProgramImage());
    }

    public void showKatakanaAsViewerToo() {
        showKatakanaAsViewerToo = true;
    }

    /** Legt fest, dass auch die internen Daten zum Katakana angezeigt werden sollen. */
    public void showInternalKatakanaDataToo() {
        showInternalKatakanaData = true;
    }

    /**
     * Erzeugt die Gui.
     *
     * Möchte man die internen Daten anzeigen, so muss man zuvor die Methode
     * showInternalKatakanaDataToo(requester) aufrufen!
     */
    public void createGui() {
        panel.setLayout(new BorderLayout());
        //GuiTools.createTitle(panel); Das sollte man wohl außerhalb entscheiden.

        panel.add(createCenterPart(), BorderLayout.CENTER);
        if (showKatakanaAsViewerToo) {
            panel.add(createButtonsPart(),  BorderLayout.SOUTH);
        }
    }

    private Component createCenterPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        panel.add(katakanaLabel.getLabel(), BorderLayout.CENTER);
        panel.add(createGermanMeaningOnLesungenAndKunLesungenAndPerhapsInternalDataPart(),
                BorderLayout.SOUTH);

        return panel;
    }

    private Component createGermanMeaningOnLesungenAndKunLesungenAndPerhapsInternalDataPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new VerticalLayout(0, VerticalLayout.BOTH));

        if (showKatakanaAsViewerToo) {
            panel.add(katakanaAsCharacterSeletion.getPanel());
        }
        panel.add(createHepburnAndSubTypePart());
        if (showInternalKatakanaData) {
            panel.add(createInternalKatakanaDataPart());
        }
        return panel;
    }

    private Component createHepburnAndSubTypePart() {
        JPanel panel = new JPanel();
        panel.setLayout(new VerticalLayout(0, VerticalLayout.BOTH));

        panel.add(hepburnSelection.getPanel());
        panel.add(subTypeSelection.getPanel());

        return panel;
    }

    private Component createInternalKatakanaDataPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new VerticalLayout(0, VerticalLayout.BOTH));

        panel.add(testCountSelection.getPanel());
        panel.add(correctTestCountSelection.getPanel());
        panel.add(lastTestDatetSelection.getPanel());
        panel.add(lastCorrectTestDateSelection.getPanel());
        panel.add(lastTenTestResultsSelection.getPanel());

        return panel;
    }

    private Component createButtonsPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new VerticalLayout(0, VerticalLayout.BOTH));

        panel.add(showKatakanaStrokesButton);

        return panel;
    }

    /** Getter für den Panel auf dem das Katakana dargestellt wird. */
    public JPanel getPanel() {
        return panel;
    }

    /** Zeigt das Katakana an. Kann mehrfach aufgerufen werden. */
    public void showKatakana(Katakana katakana, Point parentLocation) {
        katakanaCharacter = katakana.getCharacter();
        this.parentLocation = parentLocation;

        katakanaLabel.showKatakana(katakana);

        katakanaAsCharacterSeletion.setText(katakana.getCharacter());
        hepburnSelection.setText(katakana.getHepburn());
        subTypeSelection.setText(katakana.getSubType().getDescription());

        if (showInternalKatakanaData) {
            InternalKanaDataRequester requester = dataStructures.getInternalKanaDataRequester();
            InternalAdditionalKanaData data = requester.getInternalDataForKatakana(katakana);

            testCountSelection.setText(data.getTestCount());
            correctTestCountSelection.setText(data.getCorrectTestCount());
            lastTestDatetSelection.setText(data.getLastTestDate().toString());
            lastCorrectTestDateSelection.setText(data.getLastCorrectTestDate().toString());
            lastTenTestResultsSelection.setText(data.getLastTenTestResultsAsStorageString());
        }
    }

}
