package de.gecheckt.pdf.umbenenner.adapter.in.gui;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

/**
 * Unit-Tests für {@link GuiTooltipTexts}.
 * <p>
 * Prüft, dass alle öffentlichen Tooltip-Konstanten vorhanden sind, nicht leer sind
 * und den exakten Texten gemäß Spezifikation entsprechen.
 */
class GuiTooltipTextsTest {

    // -------------------------------------------------------------------------
    // Vollständigkeit und Nicht-Leerheit aller Konstanten
    // -------------------------------------------------------------------------

    @Test
    void alleKonstantenSindNichtNullUndNichtLeer() {
        List<String> fehler = new ArrayList<>();
        for (Field field : GuiTooltipTexts.class.getDeclaredFields()) {
            if (!Modifier.isPublic(field.getModifiers())
                    || !Modifier.isStatic(field.getModifiers())
                    || !Modifier.isFinal(field.getModifiers())) {
                continue;
            }
            try {
                Object value = field.get(null);
                if (value == null) {
                    fehler.add(field.getName() + " ist null");
                } else if (value instanceof String s && s.isBlank()) {
                    fehler.add(field.getName() + " ist leer");
                }
            } catch (IllegalAccessException e) {
                fehler.add(field.getName() + " nicht zugreifbar: " + e.getMessage());
            }
        }
        if (!fehler.isEmpty()) {
            org.junit.jupiter.api.Assertions.fail(
                    "Fehlerhafte Tooltip-Konstanten: " + String.join(", ", fehler));
        }
    }

    // -------------------------------------------------------------------------
    // Toolbar-Tooltips – exakter Text gemäß Spezifikation
    // -------------------------------------------------------------------------

    @Test
    void toolbar_neu_entsprichtSpezifikation() {
        assertNotNull(GuiTooltipTexts.TOOLBAR_NEU);
        assertFalse(GuiTooltipTexts.TOOLBAR_NEU.isBlank());
        org.junit.jupiter.api.Assertions.assertEquals(
                "Neue Konfiguration erstellen.",
                GuiTooltipTexts.TOOLBAR_NEU);
    }

    @Test
    void toolbar_oeffnen_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Bestehende Konfigurationsdatei (.properties) öffnen.",
                GuiTooltipTexts.TOOLBAR_OEFFNEN);
    }

    @Test
    void toolbar_speichern_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Aktuelle Konfiguration speichern.",
                GuiTooltipTexts.TOOLBAR_SPEICHERN);
    }

    @Test
    void toolbar_speichernUnter_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Konfiguration unter neuem Dateipfad speichern.",
                GuiTooltipTexts.TOOLBAR_SPEICHERN_UNTER);
    }

    @Test
    void toolbar_validieren_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Aktuelle Eingaben auf Vollständigkeit und Korrektheit prüfen.",
                GuiTooltipTexts.TOOLBAR_VALIDIEREN);
    }

    @Test
    void toolbar_technischeTests_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Dateipfade, Datenbankverbindung und KI-Erreichbarkeit prüfen.",
                GuiTooltipTexts.TOOLBAR_TECHNISCHE_TESTS);
    }

    // -------------------------------------------------------------------------
    // Pfade-Tooltips – exakter Text gemäß Spezifikation
    // -------------------------------------------------------------------------

    @Test
    void pfade_quellordner_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Ordner mit den zu verarbeitenden PDF-Dateien. Inhalt wird nicht verändert.",
                GuiTooltipTexts.PFADE_QUELLORDNER);
    }

    @Test
    void pfade_zielordner_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Ordner für die umbenannten Kopien.",
                GuiTooltipTexts.PFADE_ZIELORDNER);
    }

    @Test
    void pfade_sqlite_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Datenbank für Verarbeitungsergebnisse und Datei-Historie.",
                GuiTooltipTexts.PFADE_SQLITE);
    }

    @Test
    void pfade_prompt_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Externe Textdatei mit den KI-Anweisungen.",
                GuiTooltipTexts.PFADE_PROMPT);
    }

    // -------------------------------------------------------------------------
    // Provider-Tooltips – exakter Text gemäß Spezifikation
    // -------------------------------------------------------------------------

    @Test
    void provider_combobox_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Der KI-Dienst, der die Dateinamen generiert.",
                GuiTooltipTexts.PROVIDER_COMBOBOX);
    }

    @Test
    void provider_modell_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Das konkrete Sprachmodell des gewählten Providers.",
                GuiTooltipTexts.PROVIDER_MODELL);
    }

    // -------------------------------------------------------------------------
    // Verarbeitungslimits-Tooltips – exakter Text gemäß Spezifikation
    // -------------------------------------------------------------------------

    @Test
    void limits_maxTextCharacters_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Maximale Zeichenzahl aus dem PDF-Text. Höhere Werte = mehr Kontext, höhere Kosten.",
                GuiTooltipTexts.LIMITS_MAX_TEXT_CHARACTERS);
    }

    @Test
    void limits_maxPages_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Maximale Seitenzahl, die aus einem PDF gelesen wird.",
                GuiTooltipTexts.LIMITS_MAX_PAGES);
    }

    @Test
    void limits_maxTitleLength_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Maximale Länge des Dateinamens in Zeichen (ohne Datum und Erweiterung). Gültig: 10–120.",
                GuiTooltipTexts.LIMITS_MAX_TITLE_LENGTH);
    }

    // -------------------------------------------------------------------------
    // Verarbeitungslauf-Tab-Tooltips – exakter Text gemäß Spezifikation
    // -------------------------------------------------------------------------

    @Test
    void dateiname_uebernehmen_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Benennt die Zieldatei um und aktualisiert die Datenbank. Nicht rückgängig zu machen.",
                GuiTooltipTexts.DATEINAME_UEBERNEHMEN);
    }

    @Test
    void dateiname_zuruecksetzen_entsprichtSpezifikation() {
        org.junit.jupiter.api.Assertions.assertEquals(
                "Stellt den KI-generierten Namen wieder her, ohne zu speichern.",
                GuiTooltipTexts.DATEINAME_ZURUECKSETZEN);
    }

    // -------------------------------------------------------------------------
    // Nicht instanziierbar
    // -------------------------------------------------------------------------

    @Test
    void konstruktorWirftException() throws Exception {
        Constructor<GuiTooltipTexts> ctor = GuiTooltipTexts.class.getDeclaredConstructor();
        ctor.setAccessible(true);
        assertThrows(java.lang.reflect.InvocationTargetException.class, ctor::newInstance,
                "Der private Konstruktor muss UnsupportedOperationException werfen");
    }
}
