package tech.easyflow.ai.invoke.protocol.openai;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;

import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class OpenAiChatCompletionRequest {

    private String model;
    private List<Message> messages;
    private Boolean stream;
    private Double temperature;
    @JSONField(name = "top_p")
    @JsonProperty("top_p")
    private Double topP;
    @JSONField(name = "max_tokens")
    @JsonProperty("max_tokens")
    private Integer maxTokens;
    private Long seed;
    private List<Tool> tools;
    @JSONField(name = "tool_choice")
    @JsonProperty("tool_choice")
    private JsonNode toolChoice;
    @JSONField(name = "response_format")
    @JsonProperty("response_format")
    private ResponseFormat responseFormat;

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public List<Message> getMessages() {
        return messages;
    }

    public void setMessages(List<Message> messages) {
        this.messages = messages;
    }

    public Boolean getStream() {
        return stream;
    }

    public void setStream(Boolean stream) {
        this.stream = stream;
    }

    public Double getTemperature() {
        return temperature;
    }

    public void setTemperature(Double temperature) {
        this.temperature = temperature;
    }

    public Double getTopP() {
        return topP;
    }

    public void setTopP(Double topP) {
        this.topP = topP;
    }

    public Integer getMaxTokens() {
        return maxTokens;
    }

    public void setMaxTokens(Integer maxTokens) {
        this.maxTokens = maxTokens;
    }

    public Long getSeed() {
        return seed;
    }

    public void setSeed(Long seed) {
        this.seed = seed;
    }

    public List<Tool> getTools() {
        return tools;
    }

    public void setTools(List<Tool> tools) {
        this.tools = tools;
    }

    public JsonNode getToolChoice() {
        return toolChoice;
    }

    public void setToolChoice(JsonNode toolChoice) {
        this.toolChoice = toolChoice;
    }

    public ResponseFormat getResponseFormat() {
        return responseFormat;
    }

    public void setResponseFormat(ResponseFormat responseFormat) {
        this.responseFormat = responseFormat;
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Message {

        private String role;
        private String content;
        private List<ContentPart> contentParts;
        private String name;
        @JSONField(name = "tool_call_id")
        @JsonProperty("tool_call_id")
        private String toolCallId;
        @JSONField(name = "tool_calls")
        @JsonProperty("tool_calls")
        private List<OpenAiChatCompletionResponse.ToolCall> toolCalls;

        @JsonProperty("content")
        public void setContentNode(JsonNode contentNode) {
            if (contentNode == null || contentNode.isNull()) {
                this.content = null;
                this.contentParts = null;
                return;
            }
            if (contentNode.isTextual()) {
                this.content = contentNode.asText();
                this.contentParts = null;
                return;
            }
            if (contentNode.isArray()) {
                this.content = null;
                this.contentParts = OpenAiJsonSupport.convertContentParts(contentNode);
                return;
            }
            throw new IllegalArgumentException("message.content 仅支持字符串或数组");
        }

        @JSONField(name = "content")
        @JsonProperty("content")
        public Object getContentNode() {
            if (contentParts != null) {
                return contentParts;
            }
            return content;
        }

        public String getRole() {
            return role;
        }

        public void setRole(String role) {
            this.role = role;
        }

        @JsonIgnore
        public String getContent() {
            return content;
        }

        @JsonIgnore
        public List<ContentPart> getContentParts() {
            return contentParts;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getToolCallId() {
            return toolCallId;
        }

        public void setToolCallId(String toolCallId) {
            this.toolCallId = toolCallId;
        }

        public List<OpenAiChatCompletionResponse.ToolCall> getToolCalls() {
            return toolCalls;
        }

        public void setToolCalls(List<OpenAiChatCompletionResponse.ToolCall> toolCalls) {
            this.toolCalls = toolCalls;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class ContentPart {

        private String type;
        private String text;
        @JSONField(name = "image_url")
        @JsonProperty("image_url")
        private ImageUrl imageUrl;

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }

        public ImageUrl getImageUrl() {
            return imageUrl;
        }

        public void setImageUrl(ImageUrl imageUrl) {
            this.imageUrl = imageUrl;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class ImageUrl {

        private String url;
        private String detail;

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getDetail() {
            return detail;
        }

        public void setDetail(String detail) {
            this.detail = detail;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Tool {

        private String type;
        private ToolFunction function;

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public ToolFunction getFunction() {
            return function;
        }

        public void setFunction(ToolFunction function) {
            this.function = function;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class ToolFunction {

        private String name;
        private String description;
        private JsonNode parameters;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public JsonNode getParameters() {
            return parameters;
        }

        public void setParameters(JsonNode parameters) {
            this.parameters = parameters;
        }
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class ResponseFormat {

        private String type;
        @JSONField(name = "json_schema")
        @JsonProperty("json_schema")
        private JsonNode jsonSchema;

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public JsonNode getJsonSchema() {
            return jsonSchema;
        }

        public void setJsonSchema(JsonNode jsonSchema) {
            this.jsonSchema = jsonSchema;
        }
    }
}
