package de.duehl.vocabulary.japanese.grammar.table;

import java.util.ArrayList;
import java.util.List;

import de.duehl.basics.io.Charset;
import de.duehl.basics.io.FileHelper;
import de.duehl.basics.system.SystemTools;
import de.duehl.swing.ui.GuiTools;
import de.duehl.vocabulary.japanese.data.FumikoDataStructures;
import de.duehl.vocabulary.japanese.data.OwnList;
import de.duehl.vocabulary.japanese.data.Vocable;
import de.duehl.vocabulary.japanese.grammar.table.data.GrammarTableType;
import de.duehl.vocabulary.japanese.ui.data.FumikoUiObjects;
import de.duehl.vocabulary.japanese.ui.dialog.grammar.GrammarTableCreatorDialog;

/**
 * Diese Klasse erzeugt grammatikalische Tabellen von Verben oder Adjektiven.
 *
 * @version 1.01     2025-11-27
 * @author Christian Dühl
 */

public class GrammarTableCreator {

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

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

    /** Der Titel der zu erzeugenden Tabelle. */
    private String tableTitle;

    /** Die eigene Liste, aus der die Verben bzw. Adjektive genommen werden. */
    private OwnList ownList;

    /** Die Art der Tabelle. Möglich sind Verben, I- und Na-Adjektive. */
    private GrammarTableType grammarTableType;

    /**
     * Die Suchbegriffe, welch die Spalten der Tabelle darstellen.
     *
     * Diese sind entweder Verb- oder Adjektivformen.
     */
    private List<String> searchWords;

    /** Die Listen von Vokabeln, die in der Tabelle zeilenweise dargestellt werden. */
    private List<List<Vocable>> listOfVocablesInRow;

    /** Der HTML-Code der erstellten Tabelle. */
    private String html;

    /**
     * Der Dateiname, unter der der HTML-Code abgespeichert wurde. Ist leer,falls nicht gespeichert
     * wurde.
     */
    private String filename;

    /**
     * Gibt an, ob wirklich damit begonnen wurde, eine Tabelle zu erstellen.
     *
     * Das bedeutet, dass der Benutzer den Dialog mit OK beendet hat und man die Optionen speichern
     * sollte, auch wenn es vorkommen kann, dass gar keine Tabelle erzeugt wird, weil man keine
     * Grundformen gefunden oder der Benutzer bei der Auswahl alle abgewählt hat.
     */
    private boolean creationStarted;

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

    /** Führt die Erzeugung durch. */
    public void create() {
        GrammarTableCreatorDialog dialog = new GrammarTableCreatorDialog(dataStructures, uiObjects);
        dialog.setVisible(true);
        if (dialog.isApplied()) {
            creationStarted = true;
            tableTitle = dialog.getTableTitle();
            ownList = dialog.getOwnList();
            grammarTableType = dialog.getGrammarTableType();
            searchWords = dialog.getSearchWords();
            createTable();
        }
        else {
            creationStarted = false;
        }
    }

    private void createTable() {
        boolean created = determineFormVocables();
        if (created) {
            createHtml();
            askUserForFilename();
            saveFile();
            showInBrowser();
        }
    }

    /**
     * Erzeugt die Liste von Vokabeln pro Reihe.
     *
     * @return Gibt an, ob diese Liste sinnvoll gefüllt ist.
     */
    private boolean determineFormVocables() {
        GrammarTableRowCreator creator = new GrammarTableRowCreator(dataStructures, ownList,
                grammarTableType, searchWords, uiObjects);
        creator.create();
        if (creator.isCreated()) {
            listOfVocablesInRow = creator.getListOfVocablesInRow();
            return true;
        }
        else {
            listOfVocablesInRow = new ArrayList<>();
            return false;
        }
    }

    private void createHtml() {
        GrammarTableHtmlCreator creator = new GrammarTableHtmlCreator(listOfVocablesInRow,
                tableTitle, searchWords, dataStructures.getOptions());
        creator.create();
        html = creator.getHtml();
    }

    private void askUserForFilename() {
        filename = GuiTools.saveFileAs(uiObjects.getWindowAsComponent(),
                SystemTools.getHomeDirectory(), GuiTools.createHtmlFileFilter());
    }

    private void saveFile() {
        if (!filename.isBlank()) {
            FileHelper.writeTextToFile(html, filename, Charset.UTF_8);
        }
    }

    private void showInBrowser() {
        if (!filename.isBlank()) {
            SystemTools.openInStandardProgram(filename);
        }
    }

    /**
     * Gibt an, ob wirklich damit begonnen wurde, eine Tabelle zu erstellen.
     *
     * Das bedeutet, dass der Benutzer den Dialog mit OK beendet hat und man die Optionen speichern
     * sollte, auch wenn es vorkommen kann, dass gar keine Tabelle erzeugt wird, weil man keine
     * Grundformen gefunden oder der Benutzer bei der Auswahl alle abgewählt hat.
     */
    public boolean isCreationStarted() {
        return creationStarted;
    }

}
