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

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

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

/**
 * Creates editor states from loaded properties snapshots or from the empty start state.
 * <p>
 * The factory maps the raw `.properties` document into the GUI-side editor model without
 * introducing validation or effective-value resolution into the file load path.
 */
public final class GuiConfigurationEditorStateFactory {

    private static final String PROP_SOURCE_FOLDER = "source.folder";
    private static final String PROP_TARGET_FOLDER = "target.folder";
    private static final String PROP_SQLITE_FILE = "sqlite.file";
    private static final String PROP_PROMPT_TEMPLATE_FILE = "prompt.template.file";
    private static final String PROP_RUNTIME_LOCK_FILE = "runtime.lock.file";
    private static final String PROP_LOG_DIRECTORY = "log.directory";
    private static final String PROP_LOG_LEVEL = "log.level";
    private static final String PROP_MAX_RETRIES_TRANSIENT = "max.retries.transient";
    private static final String PROP_MAX_PAGES = "max.pages";
    private static final String PROP_MAX_TEXT_CHARACTERS = "max.text.characters";
    private static final String PROP_MAX_TITLE_LENGTH = "max.title.length";
    private static final String PROP_LOG_AI_SENSITIVE = "log.ai.sensitive";
    private static final String PROP_ACTIVE_PROVIDER = "ai.provider.active";
    private static final String PROP_CLAUDE_BASE_URL = "ai.provider.claude.baseUrl";
    private static final String PROP_CLAUDE_MODEL = "ai.provider.claude.model";
    private static final String PROP_CLAUDE_TIMEOUT = "ai.provider.claude.timeoutSeconds";
    private static final String PROP_CLAUDE_API_KEY = "ai.provider.claude.apiKey";
    private static final String PROP_OPENAI_BASE_URL = "ai.provider.openai-compatible.baseUrl";
    private static final String PROP_OPENAI_MODEL = "ai.provider.openai-compatible.model";
    private static final String PROP_OPENAI_TIMEOUT = "ai.provider.openai-compatible.timeoutSeconds";
    private static final String PROP_OPENAI_API_KEY = "ai.provider.openai-compatible.apiKey";

    private GuiConfigurationEditorStateFactory() {
        // Utility class.
    }

    /**
     * Creates an editor state from a loaded properties snapshot.
     *
     * @param snapshot the loaded file snapshot; must not be {@code null}
     * @param pendingMigrationMessage optional migration note to retain for later display
     * @return an editor state representing the loaded configuration file
     */
    public static GuiConfigurationEditorState fromPropertiesSnapshot(
            GuiConfigurationFileSnapshot snapshot,
            Optional<String> pendingMigrationMessage) {
        Properties properties = snapshot.properties();
        Map<AiProviderFamily, GuiProviderConfigurationState> providerConfigurations = new LinkedHashMap<>();
        providerConfigurations.put(AiProviderFamily.CLAUDE, new GuiProviderConfigurationState(
                propertyOrBlank(properties, PROP_CLAUDE_BASE_URL),
                propertyOrBlank(properties, PROP_CLAUDE_MODEL),
                propertyOrBlank(properties, PROP_CLAUDE_TIMEOUT),
                GuiProviderApiKeyState.unresolved(propertyOrBlank(properties, PROP_CLAUDE_API_KEY))));
        providerConfigurations.put(AiProviderFamily.OPENAI_COMPATIBLE, new GuiProviderConfigurationState(
                propertyOrBlank(properties, PROP_OPENAI_BASE_URL),
                propertyOrBlank(properties, PROP_OPENAI_MODEL),
                propertyOrBlank(properties, PROP_OPENAI_TIMEOUT),
                GuiProviderApiKeyState.unresolved(propertyOrBlank(properties, PROP_OPENAI_API_KEY))));

        GuiConfigurationValues values = new GuiConfigurationValues(
                propertyOrBlank(properties, PROP_SOURCE_FOLDER),
                propertyOrBlank(properties, PROP_TARGET_FOLDER),
                propertyOrBlank(properties, PROP_SQLITE_FILE),
                propertyOrBlank(properties, PROP_PROMPT_TEMPLATE_FILE),
                propertyOrBlank(properties, PROP_RUNTIME_LOCK_FILE),
                propertyOrBlank(properties, PROP_LOG_DIRECTORY),
                propertyOrBlank(properties, PROP_LOG_LEVEL),
                propertyOrBlank(properties, PROP_MAX_RETRIES_TRANSIENT),
                propertyOrBlank(properties, PROP_MAX_PAGES),
                propertyOrBlank(properties, PROP_MAX_TEXT_CHARACTERS),
                propertyOrBlank(properties, PROP_MAX_TITLE_LENGTH),
                propertyOrBlank(properties, PROP_LOG_AI_SENSITIVE),
                propertyOrBlank(properties, PROP_ACTIVE_PROVIDER),
                providerConfigurations);
        return new GuiConfigurationEditorState(Optional.of(snapshot), values, values, pendingMigrationMessage);
    }

    /**
     * Creates the empty editor state used at application startup when no configuration is loaded.
     *
     * @return a blank editor state
     */
    public static GuiConfigurationEditorState createBlankStartState() {
        return GuiConfigurationTemplateFactory.createBlankStartState();
    }

    private static String propertyOrBlank(Properties properties, String key) {
        String value = properties.getProperty(key);
        return value == null ? "" : value.trim();
    }
}
