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

import java.util.Objects;
import java.util.Optional;

import de.gecheckt.pdf.umbenenner.application.port.in.ResolveHistoricalFileNameUseCase;
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordLookupResult;
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordRepository;
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentTerminalSuccess;
import de.gecheckt.pdf.umbenenner.domain.model.DocumentFingerprint;

/**
 * Default implementation of {@link ResolveHistoricalFileNameUseCase}.
 * <p>
 * Queries the {@link DocumentRecordRepository} for the master record of the given fingerprint.
 * If the record represents a document that previously reached a successful terminal state,
 * the last known target filename ({@code lastTargetFileName}) is returned.
 * <p>
 * For all other terminal states (e.g. documents that finally failed without ever producing
 * a target copy) or when no master record exists, an empty {@link Optional} is returned.
 * Technical failures during the repository lookup are caught silently and treated as
 * an absent result so that the calling GUI layer is never forced to handle exceptions
 * from this query path.
 */
public class DefaultResolveHistoricalFileNameUseCase implements ResolveHistoricalFileNameUseCase {

    private final DocumentRecordRepository documentRecordRepository;

    /**
     * Creates the use case with the required document master record repository.
     *
     * @param documentRecordRepository repository for reading document master records;
     *                                 must not be {@code null}
     * @throws NullPointerException if {@code documentRecordRepository} is {@code null}
     */
    public DefaultResolveHistoricalFileNameUseCase(
            DocumentRecordRepository documentRecordRepository) {
        this.documentRecordRepository = Objects.requireNonNull(
                documentRecordRepository, "documentRecordRepository must not be null");
    }

    /**
     * Returns the last successfully written target filename for the given fingerprint,
     * or an empty {@link Optional} if no such filename exists.
     * <p>
     * The method queries the document master record. Only documents with a prior
     * successful terminal state carry a non-null {@code lastTargetFileName}. For all
     * other states (unknown, processable, finally failed) and on any technical lookup
     * failure, an empty {@link Optional} is returned.
     *
     * @param fingerprint content-based document identity; must not be {@code null}
     * @return the historical target filename, or empty if not available
     * @throws NullPointerException if {@code fingerprint} is {@code null}
     */
    @Override
    public Optional<String> resolveHistoricalFileName(DocumentFingerprint fingerprint) {
        Objects.requireNonNull(fingerprint, "fingerprint must not be null");
        try {
            DocumentRecordLookupResult result =
                    documentRecordRepository.findByFingerprint(fingerprint);
            if (result instanceof DocumentTerminalSuccess success) {
                return Optional.ofNullable(success.record().lastTargetFileName());
            }
            return Optional.empty();
        } catch (Exception e) {
            return Optional.empty();
        }
    }
}
