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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotSame;

import java.util.LinkedHashMap;
import java.util.Map;

import org.junit.jupiter.api.Test;

import de.gecheckt.pdf.umbenenner.application.config.provider.AiProviderFamily;

class GuiConfigurationValuesTest {

    @Test
    void rawGeneralValuesRemainUntouched() {
        Map<AiProviderFamily, GuiProviderConfigurationState> providerConfigurations = new LinkedHashMap<>();
        providerConfigurations.put(AiProviderFamily.CLAUDE, GuiProviderConfigurationState.blank());

        GuiConfigurationValues values = new GuiConfigurationValues(
                "./source",
                "./target",
                "./config/db.sqlite",
                "./config/prompt.txt",
                "./config/runtime.lock",
                "./logs",
                "DEBUG",
                "12",
                "34",
                "56",
                "78",
                "maybe",
                "not-a-provider-family",
                providerConfigurations);

        assertEquals("78", values.maxTitleLength());
        assertEquals("maybe", values.logAiSensitive());
        assertEquals("not-a-provider-family", values.activeProviderFamily());
        assertEquals(GuiProviderConfigurationState.blank(), values.providerConfiguration(AiProviderFamily.CLAUDE));
    }

    @Test
    void providerConfigurationMapIsDefensivelyCopied() {
        Map<AiProviderFamily, GuiProviderConfigurationState> providerConfigurations = new LinkedHashMap<>();
        providerConfigurations.put(AiProviderFamily.CLAUDE, GuiProviderConfigurationState.blank());

        GuiConfigurationValues values = new GuiConfigurationValues(
                "./source",
                "./target",
                "./config/db.sqlite",
                "./config/prompt.txt",
                "./config/runtime.lock",
                "./logs",
                "DEBUG",
                "12",
                "34",
                "56",
                "60",
                "true",
                AiProviderFamily.CLAUDE.getIdentifier(),
                providerConfigurations);

        providerConfigurations.put(AiProviderFamily.OPENAI_COMPATIBLE, GuiProviderConfigurationState.blank());

        assertNotSame(providerConfigurations, values.providerConfigurations());
        assertEquals(1, values.providerConfigurations().size());
    }

    @Test
    void withMaxTitleLength_producesIndependentCopy() {
        Map<AiProviderFamily, GuiProviderConfigurationState> providerConfigurations = new LinkedHashMap<>();
        providerConfigurations.put(AiProviderFamily.CLAUDE, GuiProviderConfigurationState.blank());

        GuiConfigurationValues original = new GuiConfigurationValues(
                "./source",
                "./target",
                "./config/db.sqlite",
                "./config/prompt.txt",
                "./config/runtime.lock",
                "./logs",
                "INFO",
                "3",
                "10",
                "1000",
                "60",
                "false",
                AiProviderFamily.CLAUDE.getIdentifier(),
                providerConfigurations);

        GuiConfigurationValues updated = original.withMaxTitleLength("80");

        assertEquals("80", updated.maxTitleLength());
        assertEquals("60", original.maxTitleLength(),
                "Original instance must remain unchanged");
        assertEquals(original.sourceFolder(), updated.sourceFolder(),
                "Unrelated fields must be preserved when copying");
    }

    @Test
    void nullMaxTitleLengthBecomesEmptyString() {
        Map<AiProviderFamily, GuiProviderConfigurationState> providerConfigurations = new LinkedHashMap<>();
        providerConfigurations.put(AiProviderFamily.CLAUDE, GuiProviderConfigurationState.blank());

        GuiConfigurationValues values = new GuiConfigurationValues(
                "./source",
                "./target",
                "./config/db.sqlite",
                "./config/prompt.txt",
                "./config/runtime.lock",
                "./logs",
                "INFO",
                "3",
                "10",
                "1000",
                null,
                "false",
                AiProviderFamily.CLAUDE.getIdentifier(),
                providerConfigurations);

        assertEquals("", values.maxTitleLength());
    }
}
