package de.assecutor.pdftool.template;

import de.assecutor.pdftool.invoice.InvoiceDraft;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.Index;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * Prüft beim Start die Verbindung zum MongoDB-Server und bricht den Start ab,
 * wenn er nicht erreichbar ist — die Anwendung setzt die Datenbank zwingend
 * voraus. Konfiguriert wird die Verbindung über MONGODB_URI in der .env-Datei.
 *
 * <p>Nach erfolgreicher Prüfung werden die Unique-Indizes auf die Template-
 * bzw. Vorbelegungs-Namen sichergestellt (Spring legt Indizes aus
 * {@code @Indexed} nicht automatisch an; auto-index-creation bleibt bewusst
 * aus, damit ein nicht erreichbarer Server zuerst diese klare Fehlermeldung
 * liefert).</p>
 */
@Component
public class MongoConnectionCheck implements ApplicationRunner {

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

    private final MongoTemplate mongoTemplate;

    public MongoConnectionCheck(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    @Override
    public void run(ApplicationArguments args) {
        try {
            mongoTemplate.executeCommand("{ ping: 1 }");
            log.info("MongoDB-Verbindung geprüft, Datenbank '{}' ist erreichbar.",
                    mongoTemplate.getDb().getName());
        } catch (Exception e) {
            throw new IllegalStateException(
                    "Keine Verbindung zum MongoDB-Server. Die Anwendung benötigt die Datenbank zwingend — "
                            + "bitte MONGODB_URI in der .env-Datei prüfen. Ursache: " + e.getMessage(), e);
        }
        ensureUniqueNameIndexes();
    }

    /** Stellt sicher, dass Template- und Vorbelegungs-Namen in der Datenbank eindeutig sind. */
    private void ensureUniqueNameIndexes() {
        Index uniqueName = new Index().on("name", Sort.Direction.ASC).unique();
        mongoTemplate.indexOps(InvoiceTemplate.class).createIndex(uniqueName);
        mongoTemplate.indexOps(InvoiceDraft.class).createIndex(uniqueName);
    }

    /** Kurzer Auswahl-Timeout, damit ein nicht erreichbarer Server den Start schnell abbricht. */
    @Bean
    static MongoClientSettingsBuilderCustomizer serverSelectionTimeoutCustomizer() {
        return builder -> builder.applyToClusterSettings(
                cluster -> cluster.serverSelectionTimeout(5, TimeUnit.SECONDS));
    }
}
