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

import java.util.List;
import java.util.Map;

import de.duehl.basics.text.html.generation.HtmlBuilder;
import de.duehl.vocabulary.japanese.common.persistence.Options;
import de.duehl.vocabulary.japanese.data.Vocable;

import static  de.duehl.vocabulary.japanese.grammar.table.GrammarTableRowCreator.NOT_FOUND_FORM;

/**
 * Diese Klasse erzeugt den HTML-Code für eine grammatikalische Tabellen von Verben oder Adjektiven.
 *
 * @version 1.01     2025-11-29
 * @author Christian Dühl
 */

public class GrammarTableHtmlCreator {

    private static final String HTML_STYLE = """
            body {
                font-size:14pt;
                background-color:white;
                color:black;
            }
            p {
                background-color:white;
                color:black;
            }
            table {
                border: 1px solid;
            }
            th {
                background-color:#DDD;
                border: 1px solid;
                margin:3px;
                padding:5px 15px 5px 15px;
            }
            td {
                border: 1px solid;
                margin:3px;
                padding:5px 15px 5px 15px;
            }
            .pronunciationChangedCell {
                background-color:#FFFFE6;
            }
            .exceptionCell {
                background-color:#FFE6E6;
            }
            .emptyCell, td.emptyCell {
                border: 0px solid;
            }
            .title {
                font-size:28pt;
            }
            .kanji {
                font-size:16pt;
            }
            .kana {
                font-size:14pt;
            }
            .romaji {
                font-size:12pt;
            }
            """.indent(4).stripTrailing();


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

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

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

    /** Die Programmoptionen. */
    private final Options options;

    /**
     * Gibt an, ob die Kanji-Darstellung angezeigt werden soll.
     *
     * Gibt es diese nicht, und wird die Kana-Datsellung nicht angezeigt, so wird statt dessen die
     * Kana.Darstellung angezeigt.
     */
    private final boolean showKanji;

    /** Gibt an, ob die Kana-Darstellung angezeigt werden soll. */
    private final boolean showKana;

    /** Gibt an, ob die Romaji-Darstellung angezeigt werden soll. */
    private final boolean showRomaji;

    /**
     * Gibt an, ob nicht gefundene Formen leer gelassen werden sollen. Anderenfalls wird ein
     * entsprechender Hinweis in Klammern eingefügt.
     */
    private final boolean leaveNotFoundFormsBlank;

    /** Das Objekt in dem das HTML aufgebaut wird. */
    private HtmlBuilder html;

    /**
     * Konstruktor.
     *
     * @param listOfVocablesInRow
     *            Die Listen von Vokabeln, die in der Tabelle zeilenweise dargestellt werden.
     * @param tableTitle
     *            Der Titel der zu erzeugenden Tabelle.
     * @param searchWords
     *            Die Suchbegriffe, welch die Spalten der Tabelle darstellen.
     * @param options
     *            Die Programmoptionen.
     */
    public GrammarTableHtmlCreator(List<List<Vocable>> listOfVocablesInRow, String tableTitle,
            List<String> searchWords, Options options) {
        this.listOfVocablesInRow = listOfVocablesInRow;
        this.tableTitle = tableTitle;
        this.searchWords = searchWords;
        this.options = options;

        showKanji = options.isGrammarTableShowKanji();
        showKana = options.isGrammarTableShowKana();
        showRomaji = options.isGrammarTableShowRomaji();
        leaveNotFoundFormsBlank = options.isGrammarTableLeaveNotFoundFormsBlank();
    }

    /** Erzeugt den HTML-Code. */
    public void create() {
        init();
        appendTableTitle();
        appendFormTable();
        appendFoot();
    }

    private void init() {
        html = new HtmlBuilder();
        html.appendHtml5HeadWithOwnExtendedCssUtf8(tableTitle, HTML_STYLE);
    }

    private void appendTableTitle() {
        html.appendPWithClass(tableTitle, "title");
        html.appendVerticalSpace();
    }

    private void appendFormTable() {
        html.appendOpeningTable();

        appendFormTableHeadRow();
        appendFormTableDataRows();

        html.appendClosingTable();
    }

    private void appendFormTableHeadRow() {
        html.appendOpeningTr();

        Map<String, String> verbMap = options.getGrammarTableVerbHeadersMap();
        Map<String, String> iAdjectiveMap = options.getGrammarTableIAdjectiveHeadersMap();
        Map<String, String> naAdjectiveMap = options.getGrammarTableNaAdjectiveHeadersMap();

        for (String searchWord : searchWords) {
            String header;
            if (!options.isGrammarTableUseUserHeaders()) {
                header = searchWord;
            }
            else if (verbMap.containsKey(searchWord)) {
                header = verbMap.get(searchWord);
            }
            else if (iAdjectiveMap.containsKey(searchWord)) {
                header = iAdjectiveMap.get(searchWord);
            }
            else if (naAdjectiveMap.containsKey(searchWord)) {
                header = naAdjectiveMap.get(searchWord);
            }
            else {
                header = searchWord;
            }
            html.appendTh(header);
        }

        html.appendClosingTr();
    }

    private void appendFormTableDataRows() {
        for (List<Vocable> vocablesInRow : listOfVocablesInRow) {
            appendFormTableDataRow(vocablesInRow);
        }
    }

    private void appendFormTableDataRow(List<Vocable> vocablesInRow) {
        html.appendOpeningTr();

        for (Vocable vocable : vocablesInRow) {
            appendTableCell(vocable);
        }

        html.appendClosingTr();
    }

    private void appendTableCell(Vocable vocable) {
        html.appendOpeningTd();

        if (vocable == NOT_FOUND_FORM) { // Ja mit != !
            if (leaveNotFoundFormsBlank) {
                // bleibt leer
            }
            else {
                html.appendP("(noch nicht vorhanden)");
            }
        }
        else {
            String kanji = vocable.getKanji();
            String kana = vocable.getKana();
            String romaji = vocable.getRomaji();

            if (kanji.isBlank()) {
                kanji = kana;
                if (showKanji && showKana) {
                    kana = "";
                }
            }

            if (showKanji) {
                html.appendP(kanji);
            }
            if (showKana) {
                html.appendP(kana);
            }
            if (showRomaji) {
                html.appendP(romaji);
            }
        }

        html.appendClosingTd();
    }

    private void appendFoot() {
        html.appendFoot();
    }

    /** Getter für den erzeugten HTML-Code. */
    public String getHtml() {
        return html.toString();
    }

}
