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

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

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

/**
 * Creates the standard GUI configuration template.
 * <p>
 * The template contains both known provider blocks, a complete set of general configuration
 * values and a clean editor state that can be used for a brand-new configuration.
 */
public final class GuiConfigurationTemplateFactory {

    private static final String SOURCE_FOLDER = "./work/local/source";
    private static final String TARGET_FOLDER = "./work/local/target";
    private static final String SQLITE_FILE = "./work/local/pdf-umbenenner.db";
    private static final String PROMPT_TEMPLATE_FILE = "./config/prompts/template.txt";
    private static final String RUNTIME_LOCK_FILE = "./work/local/pdf-umbenenner.lock";
    private static final String LOG_DIRECTORY = "./work/local/logs";
    private static final String LOG_LEVEL = "INFO";
    private static final String MAX_RETRIES_TRANSIENT = "3";
    private static final String MAX_PAGES = "10";
    private static final String MAX_TEXT_CHARACTERS = "1000";
    private static final String DEFAULT_MAX_TITLE_LENGTH = "60";

    private static final String OPENAI_BASE_URL = "https://api.openai.com/v1";
    private static final String OPENAI_MODEL = "gpt-4o-mini";
    private static final String OPENAI_TIMEOUT_SECONDS = "30";

    private static final String CLAUDE_BASE_URL = "https://api.anthropic.com";
    private static final String CLAUDE_MODEL = "claude-3-5-sonnet-20241022";
    private static final String CLAUDE_TIMEOUT_SECONDS = "60";

    private GuiConfigurationTemplateFactory() {
        // Utility class.
    }

    /**
     * Creates a brand-new clean editor state containing the standard configuration template.
     *
     * @return a clean editor state with no loaded file snapshot
     */
    public static GuiConfigurationEditorState createStandardTemplate() {
        GuiConfigurationValues standardValues = createStandardValues();
        return new GuiConfigurationEditorState(Optional.empty(), standardValues, standardValues, Optional.empty());
    }

    /**
     * Creates the editor state used when the GUI starts without a loaded configuration.
     * <p>
     * The start state contains the standard configuration template so the GUI shows the
     * default values immediately, equivalent to the explicit {@code Neu} action having been
     * triggered. No file snapshot is associated with the state.
     *
     * @return a clean editor state with the standard template values and no loaded file snapshot
     */
    public static GuiConfigurationEditorState createBlankStartState() {
        return createStandardTemplate();
    }

    /**
     * Creates a truly empty editor state without any template values.
     * <p>
     * This factory is reserved for tests that intentionally need an editor state with empty
     * field values and no provider configurations. Production startup uses
     * {@link #createBlankStartState()} which returns the standard template instead.
     *
     * @return a clean editor state without any template values
     */
    public static GuiConfigurationEditorState createEmptyStartState() {
        GuiConfigurationValues blankValues = new GuiConfigurationValues(
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                Map.of());
        return new GuiConfigurationEditorState(Optional.empty(), blankValues, blankValues, Optional.empty());
    }

    /**
     * Creates the editable values for the standard configuration template.
     *
     * @return the standard editable configuration values
     */
    public static GuiConfigurationValues createStandardValues() {
        Map<AiProviderFamily, GuiProviderConfigurationState> providerConfigurations = new LinkedHashMap<>();
        providerConfigurations.put(AiProviderFamily.CLAUDE, new GuiProviderConfigurationState(
                CLAUDE_BASE_URL,
                CLAUDE_MODEL,
                CLAUDE_TIMEOUT_SECONDS,
                GuiProviderApiKeyState.unresolved()));
        providerConfigurations.put(AiProviderFamily.OPENAI_COMPATIBLE, new GuiProviderConfigurationState(
                OPENAI_BASE_URL,
                OPENAI_MODEL,
                OPENAI_TIMEOUT_SECONDS,
                GuiProviderApiKeyState.unresolved()));

        return new GuiConfigurationValues(
                SOURCE_FOLDER,
                TARGET_FOLDER,
                SQLITE_FILE,
                PROMPT_TEMPLATE_FILE,
                RUNTIME_LOCK_FILE,
                LOG_DIRECTORY,
                LOG_LEVEL,
                MAX_RETRIES_TRANSIENT,
                MAX_PAGES,
                MAX_TEXT_CHARACTERS,
                DEFAULT_MAX_TITLE_LENGTH,
                Boolean.toString(false),
                AiProviderFamily.CLAUDE.getIdentifier(),
                providerConfigurations);
    }
}
