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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.nio.file.Path;

import org.junit.jupiter.api.Test;

class GuiConfigurationEditorStateTest {

    @Test
    void dirtyStateReflectsComparisonAgainstBaseline() {
        GuiConfigurationEditorState state = GuiConfigurationTemplateFactory.createStandardTemplate();
        GuiConfigurationValues editedValues = new GuiConfigurationValues(
                state.values().sourceFolder(),
                state.values().targetFolder(),
                state.values().sqliteFile(),
                state.values().promptTemplateFile(),
                state.values().runtimeLockFile(),
                state.values().logDirectory(),
                state.values().logLevel(),
                state.values().maxRetriesTransient(),
                state.values().maxPages(),
                state.values().maxTextCharacters(),
                state.values().maxTitleLength(),
                "maybe",
                "claude-42",
                state.values().providerConfigurations());

        GuiConfigurationEditorState dirty = state.withValues(editedValues);

        assertTrue(dirty.isDirty());
        assertEquals(state.baselineValues(), dirty.baselineValues());
        assertEquals(editedValues, dirty.values());
        assertEquals(GuiChangeState.DIRTY, dirty.changeState());

        GuiConfigurationEditorState cleanAgain = dirty.markClean();
        assertFalse(cleanAgain.isDirty());
        assertEquals(state.baselineValues(), cleanAgain.baselineValues());
        assertEquals(state.baselineValues(), cleanAgain.values());
        assertEquals(GuiChangeState.CLEAN, cleanAgain.changeState());
    }

    @Test
    void loadedFileSnapshotCanBeAttachedWithoutChangingDirtyState() {
        GuiConfigurationEditorState state = GuiConfigurationTemplateFactory.createStandardTemplate();
        GuiConfigurationFileSnapshot snapshot = new GuiConfigurationFileSnapshot(
                java.nio.file.Path.of("config/application.properties"),
                new java.util.Properties());

        GuiConfigurationEditorState withSnapshot = state.withLoadedFileSnapshot(snapshot);

        assertTrue(withSnapshot.hasLoadedFileSnapshot());
        assertFalse(withSnapshot.isNewConfiguration());
        assertEquals(snapshot, withSnapshot.loadedFileSnapshot().orElseThrow());
        assertFalse(withSnapshot.isDirty());
        assertEquals(Path.of("config/application.properties").toString(), withSnapshot.configurationPathText());
    }

    @Test
    void configurationPathTextIsEmptyWhenNoFileIsLoaded() {
        GuiConfigurationEditorState state = GuiConfigurationTemplateFactory.createBlankStartState();

        assertEquals("", state.configurationPathText());
    }

    @Test
    void pendingMigrationMessageCanBeStoredWithoutChangingDirtyState() {
        GuiConfigurationEditorState state = GuiConfigurationTemplateFactory.createStandardTemplate();
        GuiConfigurationEditorState migrated = state.withPendingMigrationMessage("Legacy import");

        assertTrue(migrated.hasPendingMigrationMessage());
        assertEquals("Legacy import", migrated.pendingMigrationMessageText());
        assertFalse(migrated.isDirty());
        assertEquals(state.values(), migrated.values());
    }

    @Test
    void resettingTheCurrentValuesToTheBaselineMakesTheEditorCleanAgain() {
        GuiConfigurationEditorState state = GuiConfigurationTemplateFactory.createStandardTemplate();
        GuiConfigurationValues editedValues = new GuiConfigurationValues(
                state.values().sourceFolder(),
                state.values().targetFolder(),
                state.values().sqliteFile(),
                state.values().promptTemplateFile(),
                state.values().runtimeLockFile(),
                state.values().logDirectory(),
                state.values().logLevel(),
                state.values().maxRetriesTransient(),
                state.values().maxPages(),
                state.values().maxTextCharacters(),
                state.values().maxTitleLength(),
                "true",
                "openai-compatible",
                state.values().providerConfigurations());

        GuiConfigurationEditorState reverted = state.withValues(editedValues).withValues(state.baselineValues());

        assertFalse(reverted.isDirty());
        assertEquals(state.baselineValues(), reverted.values());
    }
}
