package de.gecheckt.pdf.umbenenner.application.port.out;

import de.gecheckt.pdf.umbenenner.domain.model.AiRequestRepresentation;

/**
 * Outbound port for invoking an AI service over an OpenAI-compatible HTTP boundary.
 * <p>
 * This interface abstracts AI service communication, allowing the Application layer
 * to orchestrate AI-based naming without knowing about HTTP, authentication, or
 * provider-specific details.
 * <p>
 * <strong>Design principles:</strong>
 * <ul>
 *   <li>Provider is configurable (OpenAI, Azure, local LLM, etc.), not hard-coded</li>
 *   <li>Base URL, model name, and timeout are runtime configuration</li>
 *   <li>Results are returned as structured types ({@link AiInvocationResult}),
 *       never as exceptions</li>
 *   <li>Technical success (HTTP 200) is distinct from response content validity</li>
 * </ul>
 * <p>
 * <strong>Adapter responsibilities:</strong>
 * <ul>
 *   <li>Construct an HTTP request from the {@link AiRequestRepresentation}</li>
 *   <li>Apply all transport-level configuration (base URL, model, timeout, authentication)</li>
 *   <li>Execute the HTTP request against the configured endpoint</li>
 *   <li>Distinguish between successful reception of a response body and technical failure</li>
 *   <li>Return either an invocation success with raw response or a classified technical error</li>
 *   <li>Encapsulate all HTTP, JSON serialization, and authentication details</li>
 * </ul>
 * <p>
 * <strong>Non-goals of this port:</strong>
 * <ul>
 *   <li>JSON parsing of the response body (Application layer handles this)</li>
 *   <li>Validation of response content against domain rules</li>
 *   <li>Prompt construction or text formatting (Application layer does this)</li>
 *   <li>Handling of provider-specific output formats or structured output schemas</li>
 * </ul>
 * <p>
 * <strong>OpenAI compatibility:</strong> The adapter must support the OpenAI Chat
 * Completions API or a compatible endpoint. The {@code AiRequestRepresentation}
 * contains the prompt and document text; the adapter is responsible for formatting
 * these as needed (e.g., system message + user message in the Chat API).
 */
public interface AiInvocationPort {

    /**
     * Invokes an AI service with the given request representation.
     * <p>
     * This method sends a request to the configured AI endpoint and returns the result.
     * The request contains both the prompt and the document text, deterministically
     * composed by the Application layer.
     * <p>
     * <strong>Outcome distinction:</strong>
     * <ul>
     *   <li>If the HTTP call succeeds and a response body is received,
     *       {@link AiInvocationSuccess} is returned, even if the body is invalid JSON
     *       or semantically problematic. The Application layer will parse and validate
     *       the content.</li>
     *   <li>If the HTTP call fails (timeout, network error, endpoint unreachable,
     *       connection failure), {@link AiInvocationTechnicalFailure} is returned.</li>
     * </ul>
     *
     * @param request the complete request to send to the AI service; never null
     * @return an {@link AiInvocationResult} encoding either:
     *         <ul>
     *           <li>Success: response body was received (valid or not)</li>
     *           <li>Technical failure: HTTP communication failed</li>
     *         </ul>
     * @throws NullPointerException if request is null
     *
     * @see AiInvocationSuccess
     * @see AiInvocationTechnicalFailure
     */
    AiInvocationResult invoke(AiRequestRepresentation request);
}
