package de.gecheckt.pdf.umbenenner.application.usecase;

import java.util.Objects;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import de.gecheckt.pdf.umbenenner.application.port.out.DocumentPersistenceException;
import de.gecheckt.pdf.umbenenner.application.port.out.UnitOfWorkPort;
import de.gecheckt.pdf.umbenenner.domain.model.DocumentFingerprint;

/**
 * Use-Case-Implementierung für das vollständige Löschen eines Dokumenteintrags
 * aus dem Historien-Tab.
 * <p>
 * Löscht innerhalb einer Transaktion in der korrekten Reihenfolge, um den
 * Foreign-Key-Constraint zwischen {@code processing_attempt.fingerprint} und
 * {@code document_record.fingerprint} zu erfüllen (kein {@code ON DELETE CASCADE}):
 * <ol>
 *   <li>Alle {@code processing_attempt}-Einträge zum Fingerprint</li>
 *   <li>Den {@code document_record}-Stammsatz zum Fingerprint</li>
 * </ol>
 * Die Operation ist idempotent: wenn kein Datensatz für den Fingerprint existiert,
 * kehrt die Methode stillschweigend zurück.
 * <p>
 * <strong>Hinweis:</strong> Diese Aktion ist destruktiv und nicht rückgängig zu machen.
 * Die GUI muss vor dem Aufruf einen Bestätigungsdialog anzeigen.
 */
public class DefaultDeleteDocumentHistoryUseCase {

    private static final Logger logger = LogManager.getLogger(DefaultDeleteDocumentHistoryUseCase.class);

    private final UnitOfWorkPort unitOfWorkPort;

    /**
     * Erzeugt den Use-Case mit dem erforderlichen Persistenz-Port.
     *
     * @param unitOfWorkPort Port für transaktionale Persistenzoperationen; darf nicht {@code null} sein
     * @throws NullPointerException wenn {@code unitOfWorkPort} null ist
     */
    public DefaultDeleteDocumentHistoryUseCase(UnitOfWorkPort unitOfWorkPort) {
        this.unitOfWorkPort = Objects.requireNonNull(unitOfWorkPort, "unitOfWorkPort darf nicht null sein");
    }

    /**
     * Löscht den Stammsatz und alle Verarbeitungsversuche für den angegebenen Fingerprint.
     * <p>
     * Die Löschung erfolgt in einer einzigen Transaktion. Versuche werden vor dem
     * Stammsatz gelöscht, damit der Foreign-Key-Constraint eingehalten wird.
     *
     * @param fingerprint der Dokumentbezeichner, dessen Daten vollständig gelöscht werden sollen;
     *                    darf nicht {@code null} sein
     * @throws DocumentPersistenceException bei technischen Datenbankfehlern
     * @throws NullPointerException         wenn {@code fingerprint} null ist
     */
    public void deleteHistory(DocumentFingerprint fingerprint) {
        Objects.requireNonNull(fingerprint, "fingerprint darf nicht null sein");

        // Nutzung der bestehenden Transaktion mit korrekter Löschreihenfolge:
        // zuerst Versuche, dann Stammsatz (FK-Constraint)
        unitOfWorkPort.executeInTransaction(tx -> tx.resetDocumentByFingerprint(fingerprint));

        logger.info("Dokumenteintrag vollständig gelöscht für Fingerprint: {}", fingerprint.sha256Hex());
    }
}
