package de.effigenix.infrastructure.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;

import java.sql.DriverManager;
import java.util.Map;

/**
 * Prüft vor dem Context-Start, ob die Datenbank erreichbar ist.
 * Schlägt die Verbindung fehl, wird das Spring-Profil "no-db" aktiviert.
 * Damit werden JPA, DataSource und Liquibase ausgeschlossen und Stub-Beans registriert.
 *
 * WICHTIG: Die Autoconfiguration-Exclusions werden hier programmatisch gesetzt,
 * weil application-no-db.yml nicht geladen wird, wenn das Profil erst im
 * ApplicationContextInitializer (nach prepareEnvironment) hinzugefügt wird.
 */
public class DatabaseProfileInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    private static final Logger log = LoggerFactory.getLogger(DatabaseProfileInitializer.class);

    private static final String AUTOCONFIGURE_EXCLUDE = String.join(",",
            "org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration",
            "org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration",
            "org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration",
            "org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration",
            "org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration");

    @Override
    public void initialize(ConfigurableApplicationContext ctx) {
        var env = (ConfigurableEnvironment) ctx.getEnvironment();

        if (env.acceptsProfiles(org.springframework.core.env.Profiles.of("no-db"))) {
            log.info("Profil 'no-db' bereits aktiv – überspringe DB-Check.");
            applyNoDbProperties(env);
            return;
        }

        var url  = env.getProperty("spring.datasource.url",      "jdbc:postgresql://localhost:5432/effigenix");
        var user = env.getProperty("spring.datasource.username", "effigenix");
        var pass = env.getProperty("spring.datasource.password", "effigenix");

        try (var ignored = DriverManager.getConnection(url, user, pass)) {
            log.debug("Datenbankverbindung erfolgreich – normaler Start.");
        } catch (Exception e) {
            log.warn("⚠️  Keine Datenbankverbindung – Stub-Modus aktiv. Einige Features sind nicht verfügbar. ({})", e.getMessage());
            env.addActiveProfile("no-db");
            applyNoDbProperties(env);
        }
    }

    private void applyNoDbProperties(ConfigurableEnvironment env) {
        env.getPropertySources().addFirst(new MapPropertySource("no-db-overrides", Map.of(
                "spring.autoconfigure.exclude", AUTOCONFIGURE_EXCLUDE
        )));
    }
}
