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

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

/**
 * Represents a successfully parsed AI response with the expected JSON structure.
 * <p>
 * This record captures the three core fields that should be present in the AI's JSON response,
 * extracted and structurally validated. The values are NOT yet semantically validated
 * (e.g., title length, date format validity), but are known to exist and be parseable as strings.
 * <p>
 * <strong>Field semantics:</strong>
 * <ul>
 *   <li>{@link #title()} — the title string extracted from the AI response.
 *       Non-null, but may require further validation (length, special characters, etc.).</li>
 *   <li>{@link #reasoning()} — the AI's justification or explanation.
 *       Non-null (may be empty), extracted as-is from the response.</li>
 *   <li>{@link #dateString()} — the date string from the AI response, if present.
 *       Optional; if present, will require format validation (e.g., YYYY-MM-DD).
 *       If absent, the application may use a fallback date.</li>
 * </ul>
 * <p>
 * <strong>Distinction from other types:</strong>
 * <ul>
 *   <li>{@link AiRawResponse} — entire uninterpreted response body</li>
 *   <li>{@link ParsedAiResponse} — JSON structure extracted and fields present (this type)</li>
 *   <li>{@link NamingProposal} — fields semantically validated and ready for use</li>
 * </ul>
 * <p>
 * <strong>Usage:</strong> The Application layer receives an {@link AiInvocationSuccess},
 * parses the raw response body, and produces either a {@code ParsedAiResponse} (if the JSON
 * structure is sound) or an {@link AiResponseParsingFailure} (if parsing or mandatory field
 * extraction fails). Later processing steps then validate the parsed values semantically.
 *
 * @param title       the title string extracted from the JSON; never null
 * @param reasoning   the reasoning/explanation string extracted; never null (may be empty)
 * @param dateString  optional date string (e.g., "2026-02-11"); empty Optional if not present
 */
public record ParsedAiResponse(
        String title,
        String reasoning,
        Optional<String> dateString) {

    /**
     * Compact constructor validating mandatory fields.
     *
     * @throws NullPointerException if any field is null
     */
    public ParsedAiResponse {
        Objects.requireNonNull(title, "title must not be null");
        Objects.requireNonNull(reasoning, "reasoning must not be null");
        Objects.requireNonNull(dateString, "dateString must not be null (use empty Optional if no date)");
    }

    /**
     * Convenience constructor that accepts a nullable date string.
     *
     * @param title       the title string (non-null)
     * @param reasoning   the reasoning string (non-null)
     * @param dateString  the date string, or null to represent "not present"
     * @return a new ParsedAiResponse with the date wrapped in Optional
     */
    public static ParsedAiResponse of(String title, String reasoning, String dateString) {
        return new ParsedAiResponse(title, reasoning, Optional.ofNullable(dateString));
    }
}
