using System.Collections.Generic;

using Newtonsoft.Json;


namespace AIRuntime.Runtime.Providers.OpenAI
{
    internal sealed class OpenAIChatRequest
    {
        [JsonProperty("model")]
        public string Model { get; set; }

        [JsonProperty("messages")]
        public List<OpenAIMessage> Messages { get; } =
            new List<OpenAIMessage>();

        [JsonProperty("tags", NullValueHandling = NullValueHandling.Ignore)]
        public List<string> Tags { get; set; }

        [JsonProperty("tools", NullValueHandling = NullValueHandling.Ignore)]
        public List<OpenAITool> Tools { get; set; }

        [JsonProperty("tool_choice", NullValueHandling = NullValueHandling.Ignore)]
        public string ToolChoice { get; set; }

        [JsonProperty("chat_template_kwargs", NullValueHandling = NullValueHandling.Ignore)]
        public OpenAIChatTemplateArguments ChatTemplateArguments { get; set; }

        [JsonProperty("temperature")]
        public double Temperature { get; set; }

        [JsonProperty("max_completion_tokens", NullValueHandling = NullValueHandling.Ignore)]
        public int? MaxCompletionTokens { get; set; }

        [JsonProperty("max_tokens", NullValueHandling = NullValueHandling.Ignore)]
        public int? MaxTokens { get; set; }

        [JsonProperty("reasoning_effort", NullValueHandling = NullValueHandling.Ignore)]
        public string ReasoningEffort { get; set; }

        [JsonProperty("reasoning", NullValueHandling = NullValueHandling.Ignore)]
        public OpenAIReasoningArguments Reasoning { get; set; }

        [JsonProperty("stream")]
        public bool Stream { get; set; }
    }


    internal sealed class OpenAIReasoningArguments
    {
        [JsonProperty("effort")]
        public string Effort { get; set; }

        [JsonProperty("exclude")]
        public bool Exclude { get; set; }
    }


    internal sealed class OpenAIChatTemplateArguments
    {
        [JsonProperty("enable_thinking")]
        public bool EnableThinking { get; set; }
    }


    internal sealed class OpenAIMessage
    {
        [JsonProperty("role")]
        public string Role { get; set; }

        [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
        public object Content { get; set; }

        [JsonProperty("tool_call_id", NullValueHandling = NullValueHandling.Ignore)]
        public string ToolCallId { get; set; }

        [JsonProperty("tool_calls", NullValueHandling = NullValueHandling.Ignore)]
        public List<OpenAIToolCall> ToolCalls { get; set; }
    }


    internal sealed class OpenAIContentPart
    {
        [JsonProperty("type")]
        public string Type { get; set; }

        [JsonProperty("text", NullValueHandling = NullValueHandling.Ignore)]
        public string Text { get; set; }

        [JsonProperty("image_url", NullValueHandling = NullValueHandling.Ignore)]
        public OpenAIImageUrl ImageUrl { get; set; }
    }


    internal sealed class OpenAIImageUrl
    {
        [JsonProperty("url")]
        public string Url { get; set; }
    }


    internal sealed class OpenAITool
    {
        [JsonProperty("type")]
        public string Type { get; set; } =
            "function";

        [JsonProperty("function")]
        public OpenAIFunction Function { get; set; }
    }


    internal sealed class OpenAIFunction
    {
        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
        public string Description { get; set; }

        [JsonProperty("parameters")]
        public object Parameters { get; set; }
    }


    internal sealed class OpenAIToolCall
    {
        [JsonProperty("id")]
        public string Id { get; set; }

        [JsonProperty("type")]
        public string Type { get; set; } =
            "function";

        [JsonProperty("function")]
        public OpenAIFunctionCall Function { get; set; }
    }


    internal sealed class OpenAIFunctionCall
    {
        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("arguments")]
        public string Arguments { get; set; }
    }


    internal sealed class OpenAIChatResponse
    {
        [JsonProperty("choices")]
        public List<OpenAIChoice> Choices { get; set; }
    }


    internal sealed class OpenAIChoice
    {
        [JsonProperty("message")]
        public OpenAIMessage Message { get; set; }
    }
}
