/*
 * Copyright 2025 Conductor Authors.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.conductoross.conductor.ai.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.conductoross.conductor.common.Documented;

import com.netflix.conductor.common.metadata.SchemaDef;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = true)
public class ChatCompletion extends LLMWorkerInput {

    public static final String NAME = "LLM_CHAT_COMPLETE";

    private String instructions;

    @Documented(usage = "History of messages")
    private List<ChatMessage> messages = new ArrayList<>();

    @Documented(
            usage =
                    "Produces JSON as output if set to true.  Depending on the model you MUST including JSON word as part of the prompt")
    private boolean jsonOutput;

    @Documented(usage = "Enable Google Search Retrieval for Gemini models")
    private boolean googleSearchRetrieval;

    @Documented(
            usage =
                    "Optional schema for the prompt inputs.  If supplied, the inputs MUST conform to the schema")
    private SchemaDef inputSchema;

    @Documented(
            usage =
                    """
                        Output schema for the response generated by LLM.  Useful when using #jsonOutput.  If specified, the LLM output is validated against the schema.
                        If the validation fails, the request is retried N number of times.  Default value for N is 3 and depends on the retryCount defined in the taskDefinition.
                        When retrying, no waits or backoff are applied.
                        """)
    private SchemaDef outputSchema;

    private String userInput;

    @Documented(
            usage =
                    """
                        Tools to be used.  Tools MUST be registered conductor workers or supported integrations
                        """)
    private List<ToolSpec> tools = new ArrayList<>();

    @Documented(usage = "Integrations for the mcp tools")
    private Map<String, ChatMessage.Role> participants = Map.of();

    // refers to HTTP content type
    private String outputMimeType;

    // Used for thinking models
    @Documented(
            usage =
                    "Token budget for extended thinking/reasoning before the model generates its final response. Supported by Anthropic and Google Gemini.")
    private int thinkingTokenLimit;

    @Documented(usage = "Reasoning effort level: low, medium, or high. Supported by OpenAI models.")
    private String reasoningEffort;

    @Documented(
            usage =
                    """
                    Reasoning summary mode. When set, the provider returns chain-of-thought reasoning text on the response, available via the 'reasoning' field on the task output (and the reasoning_tokens count via 'reasoningTokens' where supported).
                    - OpenAI / Azure OpenAI (Responses API, gpt-5.x and o-series): values 'auto', 'concise', 'detailed' — passed through as 'reasoning.summary'.
                    - Anthropic (Claude with extended thinking): any non-blank value opts in to surfacing the thinking blocks. The actual thinking budget is configured via 'thinkingTokenLimit'.
                    - Google Gemini (2.5+): any non-blank value enables 'includeThoughts' on the request so the model returns thought summaries. The thinking budget is configured via 'thinkingTokenLimit'.
                    """)
    private String reasoningSummary;

    @Documented(usage = "Location where the results should be stored.  Useful for media generation")
    private String outputLocation;

    @Documented(
            usage =
                    "ID of a previous response to chain multi-turn conversations without resending full message history. Supported by OpenAI and Azure OpenAI (Responses API).")
    private String previousResponseId;

    @Documented(
            usage =
                    "Enable built-in web search. The LLM can search the web for real-time information. Supported by OpenAI, Anthropic, and Google Gemini.")
    private boolean webSearch;

    @Documented(
            usage =
                    "Enable built-in code execution. The LLM can write and run code in a sandboxed environment. Supported by OpenAI (code_interpreter), Anthropic (code_execution), and Google Gemini (codeExecution).")
    private boolean codeInterpreter;

    @Documented(
            usage =
                    "Vector store IDs for file search. The LLM can search through uploaded files. Supported by OpenAI only.")
    private List<String> fileSearchVectorStoreIds;

    // Audio output
    private String voice;

    public String getPrompt() {
        return instructions;
    }
}
