package de.gecheckt.pdf.umbenenner.domain.model;

import java.time.LocalDate;
import java.util.Objects;

/**
 * A validated naming proposal derived from AI analysis of a document.
 * <p>
 * This record represents the core results of the AI-based naming stage:
 * a proposed date, a proposed title, and the AI's reasoning. All three fields
 * have been validated according to application rules at the time of creation.
 * <p>
 * <strong>Field semantics:</strong>
 * <ul>
 *   <li>{@link #resolvedDate()} — the effective date for the naming proposal,
 *       either supplied by the AI or derived as a fallback. Always non-null.</li>
 *   <li>{@link #dateSource()} — indicates whether the date came from the AI
 *       or is a fallback to the current system date.</li>
 *   <li>{@link #validatedTitle()} — the title extracted and validated from
 *       the AI response. Guaranteed to be non-null, non-empty, and compliant
 *       with documented title rules (within the configured maximum base title
 *       length, no prohibited special characters, etc.).</li>
 *   <li>{@link #aiReasoning()} — the justification or explanation provided
 *       by the AI for its proposal. Non-null (may be empty in edge cases,
 *       though normally expected to be meaningful).</li>
 * </ul>
 * <p>
 * <strong>Not included in this proposal:</strong>
 * <ul>
 *   <li>Final target filename (e.g., with {@code (1)}, {@code (2)} duplicates)</li>
 *   <li>Target file path or copy operation</li>
 *   <li>Windows-specific filename character transformations</li>
 * </ul>
 * <p>
 * <strong>Persistence:</strong> The naming proposal is persistently stored as part
 * of the processing attempt history for reproducibility and audit.
 *
 * @param resolvedDate   the effective date (never null); derived from AI or fallback
 * @param dateSource     origin of the date ({@link DateSource#AI_PROVIDED} or
 *                       {@link DateSource#FALLBACK_CURRENT}); never null
 * @param validatedTitle the title validated per application rules (non-null, non-empty,
 *                       within the configured maximum base title length as defined in
 *                       the application configuration)
 * @param aiReasoning    the AI's explanation for the proposal (non-null, may be empty)
 */
public record NamingProposal(
        LocalDate resolvedDate,
        DateSource dateSource,
        String validatedTitle,
        String aiReasoning) {

    /**
     * Compact constructor validating all mandatory fields.
     *
     * @throws NullPointerException if any field is null
     * @throws IllegalArgumentException if validatedTitle is empty
     */
    public NamingProposal {
        Objects.requireNonNull(resolvedDate, "resolvedDate must not be null");
        Objects.requireNonNull(dateSource, "dateSource must not be null");
        Objects.requireNonNull(validatedTitle, "validatedTitle must not be null");
        if (validatedTitle.isEmpty()) {
            throw new IllegalArgumentException("validatedTitle must not be empty");
        }
        Objects.requireNonNull(aiReasoning, "aiReasoning must not be null");
    }
}
