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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Comparator;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.TableRowSorter;

import de.duehl.basics.collections.CollectionsHelper;
import de.duehl.basics.text.NumberString;
import de.duehl.swing.ui.GuiTools;
import de.duehl.swing.ui.dialogs.base.NonModalFrameDialogBase;
import de.duehl.swing.ui.tables.ButtonColumn;
import de.duehl.vocabulary.japanese.data.FumikoDataStructures;
import de.duehl.vocabulary.japanese.data.symbol.Hiragana;
import de.duehl.vocabulary.japanese.ui.data.FumikoUiObjects;
import de.duehl.vocabulary.japanese.ui.dialog.kana.hiraganatest.components.HiraganaDetailDialog;
import de.duehl.vocabulary.japanese.ui.dialog.table.hiragana.HiraganaTableColumnModel;
import de.duehl.vocabulary.japanese.ui.dialog.table.hiragana.HiraganaTableModel;
import de.duehl.vocabulary.japanese.ui.dialog.table.hiragana.HiraganaTableRenderer;

import static de.duehl.vocabulary.japanese.ui.dialog.vocables.lister.VocabularyListerDialog.createLastTenTestResultsSorter;

/**
 * Diese Klasse zeigt die Hiragana in Form einer Liste an.
 *
 * @version 1.01     2026-08-21
 * @author Christian Dühl
 */

public class HiraganaTableDialog extends NonModalFrameDialogBase {

    private static final Dimension DIALOG_DIMENSION = new Dimension(1500, 1000);

    private static final Color TABLE_FOREGROUND = new Color(0, 0, 255);
    private static final Color TABLE_BACKGROUND = new Color(240, 240, 255);

    private static final float DEFAULT_FONT_SIZE = 15f;


    /** Die Liste mit den bekannten Hiragana. */
    private final List<Hiragana> hiraganaList;

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

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

    /** Die Tabelle. */
    private final JTable table;

    /** Das Modell der anzuzeigenden Tabelle. */
    private final HiraganaTableModel tableModel;

    /** Der Renderer der Tabelle. */
    private final HiraganaTableRenderer tableRenderer;

    /** Die ScrollPane um die Vokabeln. */
    private JScrollPane scrollPane;

    /** Button um die Schriftgröße der Tabelle zu erhöhen. */
    private final JButton increaseFontSizeButton;

    /** Button um die Schriftgröße der Tabelle zu verringern. */
    private final JButton standardFontSizeButton;

    /** Button um die Schriftgröße der Tabelle zu verringern. */
    private final JButton decreaseFontSizeButton;

    /**
     * Konstruktor für die Anzeige aller bekannten Hiragana.
     *
     * @param dataStructures
     *            Die Datenstrukturen des Vokabeltrainers.
     * @param uiObjects
     *            Die häufig verwendeten Funktionen der grafischen Oberfläche des Vokabeltrainers.
     */
    public HiraganaTableDialog(FumikoDataStructures dataStructures, FumikoUiObjects uiObjects) {
        super(uiObjects.getGuiLocation(), uiObjects.getProgramImage(), "Liste mit den Hiragana.",
                DIALOG_DIMENSION);
        addEscapeBehaviour();

        this.hiraganaList = CollectionsHelper.arrayToList(Hiragana.values());
        this.dataStructures = dataStructures;
        this.uiObjects = uiObjects;

        table = new JTable();
        tableModel = new HiraganaTableModel(hiraganaList, dataStructures);
        tableRenderer = new HiraganaTableRenderer(TABLE_FOREGROUND, TABLE_BACKGROUND);
        increaseFontSizeButton = new JButton();
        standardFontSizeButton = new JButton();
        decreaseFontSizeButton = new JButton();

        init();
        fillDialog();
    }

    private void init() {
        initTable();
        initScrollPane();
    }

    private void initTable() {
        initTableModel();
        initTableColumnModel();
        initTableRenderer();
        setTableSelectionMode();
        setTableRowHight();
        switchReorderingOfTableColumnsOff();
        initTableButtonEditorAndRenderer();
        initTableSorter();
    }

    private void initTableModel() {
        table.setModel(tableModel);
    }

    private void initTableColumnModel() {
        table.setColumnModel(new HiraganaTableColumnModel());
    }

    private void initTableRenderer() {
        tableRenderer.setFontSize(DEFAULT_FONT_SIZE);
        table.setDefaultRenderer(Object.class, tableRenderer);
    }

    private void setTableSelectionMode() {
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        //table.getSelectionModel().addListSelectionListener(createSelectionListener());
    }

    private void setTableRowHight() {
        tableRenderer.initRowHeightOfTable(table);
    }

    private void switchReorderingOfTableColumnsOff() {
        table.getTableHeader().setReorderingAllowed(false); // verschieben der Spalten verhindern
    }

    private void initTableButtonEditorAndRenderer() {
        new ButtonColumn(table, row -> reactOnShowHiraganaDetailsButtonClick(row), 9);
    }

    private void reactOnShowHiraganaDetailsButtonClick(int row) {
        Hiragana hiragana = hiraganaList.get(row);
        HiraganaDetailDialog dialog = new HiraganaDetailDialog(hiragana, dataStructures, uiObjects,
                getParentLocation(), getProgramImage());
        dialog.setVisible(true);
    }

    private void initTableSorter() {
        TableRowSorter<HiraganaTableModel> sorter = new TableRowSorter<>(tableModel);

        /*
         * Die letzten zehn Ergebnisse werden leider alphanumerisch sortiert, das ist nicht so
         * schön. Daher mache ich es so:
         */
        Comparator<String> lastTenTestResultsSorter = createLastTenTestResultsSorter();

        int indexOfLastTen = 8;
        sorter.setComparator(indexOfLastTen, lastTenTestResultsSorter);

        table.setRowSorter(sorter);
    }

    private void initScrollPane() {
        scrollPane = GuiTools.createScrollPane(table);
    }

    /** Baut die Gui auf. */
    @Override
    protected void populateDialog() {
        initElements();

        add(createCenterPart(), BorderLayout.CENTER);
        add(createButtonsPart(),  BorderLayout.SOUTH);

        GuiTools.scrollScrollbarToMinimumLater(scrollPane);
    }

    private void initElements() {
        initIncreaseFontSizeButton();
        initStandardFontSizeButton();
        initDecreaseFontSizeButton();
    }

    private void initIncreaseFontSizeButton() {
        increaseFontSizeButton.setText("+");
        increaseFontSizeButton.addActionListener(e -> increaseFontSize());
    }

    private void increaseFontSize() {
        tableRenderer.increaseFontSize();
        tableRenderer.initRowHeightOfTable(table);
        table.repaint();
    }

    private void initStandardFontSizeButton() {
        String text = "default size (" + NumberString.twoDecimalPlaces(DEFAULT_FONT_SIZE) + ")";
        standardFontSizeButton.setText(text);
        standardFontSizeButton.addActionListener(e -> standardFontSize());
    }

    private void standardFontSize() {
        tableRenderer.setFontSize(DEFAULT_FONT_SIZE);
        tableRenderer.initRowHeightOfTable(table);
        table.repaint();
    }

    private void initDecreaseFontSizeButton() {
        decreaseFontSizeButton.setText("-");
        decreaseFontSizeButton.addActionListener(e -> decreaseFontSize());
    }

    private void decreaseFontSize() {
        tableRenderer.decreaseFontSize();
        tableRenderer.initRowHeightOfTable(table);
        table.repaint();
    }

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

        panel.add(scrollPane, BorderLayout.CENTER);

        return panel;
    }

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

        panel.add(createFontSizeAndColorButtonsPart(), BorderLayout.WEST);
        panel.add(createQuitButton(), BorderLayout.EAST);

        return panel;
    }

    private Component createFontSizeAndColorButtonsPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.LEFT, 3, 0));

        panel.add(createFontSizeButtonsPart());
        panel.add(createColorButtonsPart());

        return panel;
    }

    private Component createFontSizeButtonsPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.LEFT, 3, 0));

        panel.add(decreaseFontSizeButton);
        panel.add(standardFontSizeButton);
        panel.add(increaseFontSizeButton);

        return panel;
    }

    private Component createColorButtonsPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.LEFT, 3, 0));

        panel.add(createSwitchForegroundColorButton());
        panel.add(createSwitchBackgroundColorButton());

        return panel;
    }

    private Component createSwitchForegroundColorButton() {
        JButton button = new JButton("toggle Vordergrundfarbe");
        button.addActionListener(e -> toggleColorForegroundDependingOnLastSuccess());
        return button;
    }

    private void toggleColorForegroundDependingOnLastSuccess() {
        tableRenderer.toggleColorForegroundDependingOnLastSuccess();
        table.repaint();
    }

    private Component createSwitchBackgroundColorButton() {
        JButton button = new JButton("toggle Hintergrundfarbe");
        button.addActionListener(e -> toggleColorBackgroundDependingOnLastSuccess());
        return button;
    }

    private void toggleColorBackgroundDependingOnLastSuccess() {
        tableRenderer.toggleColorBackgroundDependingOnLastSuccess();
        table.repaint();
    }

    private Component createQuitButton() {
        JButton button = new JButton("Beenden");
        button.addActionListener(e -> quit());
        return button;
    }

    private void quit() {
        closeDialog();
    }

}
