// Package aiwire 定义 AI 网关的线格式类型:OpenAI Responses / Chat Completions /
// Anthropic Messages / Embeddings 与通用记账、错误、模型列表结构。上游统一为
// OCI OpenAI 兼容面。
package aiwire

import (
	"encoding/json"
	"strings"
)

// StringList 兼容 OpenAI stop 的 string 与 []string 两种线格式。
type StringList []string

func (s *StringList) UnmarshalJSON(b []byte) error {
	if len(b) > 0 && b[0] == '"' {
		var one string
		if err := json.Unmarshal(b, &one); err != nil {
			return err
		}
		*s = StringList{one}
		return nil
	}
	var many []string
	if err := json.Unmarshal(b, &many); err != nil {
		return err
	}
	*s = many
	return nil
}

// Usage 是 token 用量。
type Usage struct {
	PromptTokens     int `json:"prompt_tokens"`
	CompletionTokens int `json:"completion_tokens"`
	TotalTokens      int `json:"total_tokens"`
	// PromptTokensDetails 携带缓存命中细分;OCI 为隐式 prompt 缓存,只有读取计数
	PromptTokensDetails *PromptTokensDetails `json:"prompt_tokens_details,omitempty"`
}

// PromptTokensDetails 是输入 token 细分(OpenAI prompt_tokens_details 同构)。
type PromptTokensDetails struct {
	CachedTokens int `json:"cached_tokens"`
}

// CachedTokens 返回缓存命中读取的 token 数;无细分时为 0。
func (u *Usage) CachedTokens() int {
	if u == nil || u.PromptTokensDetails == nil {
		return 0
	}
	return u.PromptTokensDetails.CachedTokens
}

// Model 是 /v1/models 列表项。
type Model struct {
	ID      string `json:"id"`
	Object  string `json:"object"`
	Created int64  `json:"created"`
	OwnedBy string `json:"owned_by"`
}

// ModelList 是 /v1/models 响应体。
type ModelList struct {
	Object string  `json:"object"`
	Data   []Model `json:"data"`
}

// ErrorBody 是 OpenAI 格式错误响应。
type ErrorBody struct {
	Error ErrorDetail `json:"error"`
}

// ErrorDetail 是错误明细。
type ErrorDetail struct {
	Message string `json:"message"`
	Type    string `json:"type"`
	Code    string `json:"code,omitempty"`
}

// ---- Chat Completions 线格式(/ai/v1/chat/completions,Tier 2 兼容层)----

// ChatRequest 是 OpenAI /v1/chat/completions 请求体;只声明网关读取的字段,
// 无对应物的字段(stop / seed / n / penalty 等)由 JSON 解码天然忽略。
type ChatRequest struct {
	Model               string          `json:"model"`
	Messages            []ChatMessage   `json:"messages"`
	MaxTokens           *int            `json:"max_tokens,omitempty"`
	MaxCompletionTokens *int            `json:"max_completion_tokens,omitempty"`
	Temperature         *float64        `json:"temperature,omitempty"`
	TopP                *float64        `json:"top_p,omitempty"`
	ParallelToolCalls   *bool           `json:"parallel_tool_calls,omitempty"`
	Stream              bool            `json:"stream,omitempty"`
	StreamOptions       *StreamOptions  `json:"stream_options,omitempty"`
	Tools               []Tool          `json:"tools,omitempty"`
	ToolChoice          json.RawMessage `json:"tool_choice,omitempty"`
	ResponseFormat      *ResponseFormat `json:"response_format,omitempty"`
	ReasoningEffort     string          `json:"reasoning_effort,omitempty"`
}

// StreamOptions 控制流式末尾是否附带 usage 块。
type StreamOptions struct {
	IncludeUsage bool `json:"include_usage"`
}

// ChatMessage 是请求与非流式响应共用的消息结构。
type ChatMessage struct {
	Role       string     `json:"role"`
	Content    Content    `json:"content"`
	ToolCalls  []ToolCall `json:"tool_calls,omitempty"`
	ToolCallID string     `json:"tool_call_id,omitempty"`
}

// Content 兼容 string 与多模态块数组两种线格式,序列化时保形。
type Content struct {
	Text    string
	Parts   []ContentPart
	IsArray bool
}

func (c *Content) UnmarshalJSON(b []byte) error {
	t := strings.TrimSpace(string(b))
	if t == "null" {
		return nil
	}
	if strings.HasPrefix(t, "[") {
		c.IsArray = true
		return json.Unmarshal(b, &c.Parts)
	}
	return json.Unmarshal(b, &c.Text)
}

func (c Content) MarshalJSON() ([]byte, error) {
	if c.IsArray {
		return json.Marshal(c.Parts)
	}
	return json.Marshal(c.Text)
}

// NewTextContent 构造字符串形态的内容。
func NewTextContent(text string) Content {
	return Content{Text: text}
}

// JoinText 拍平内容为纯文本(数组形态拼接 text 块)。
func (c Content) JoinText() string {
	if !c.IsArray {
		return c.Text
	}
	var sb strings.Builder
	for _, p := range c.Parts {
		if p.Type == "" || p.Type == "text" {
			sb.WriteString(p.Text)
		}
	}
	return sb.String()
}

// ContentPart 是块数组中的一段;text 与 image_url 被网关承接,其余类型拒绝。
type ContentPart struct {
	Type     string    `json:"type"`
	Text     string    `json:"text,omitempty"`
	ImageURL *ImageURL `json:"image_url,omitempty"`
}

// ImageURL 是 image_url 块负载;url 为 data URI(base64)或公网地址。
type ImageURL struct {
	URL    string `json:"url"`
	Detail string `json:"detail,omitempty"`
}

// Tool 是嵌套形态的 function 工具定义。
type Tool struct {
	Type     string      `json:"type"`
	Function FunctionDef `json:"function"`
}

// FunctionDef 描述工具的名称与 JSON Schema 参数。
type FunctionDef struct {
	Name        string          `json:"name"`
	Description string          `json:"description,omitempty"`
	Parameters  json.RawMessage `json:"parameters,omitempty"`
}

// ToolCall 是助手消息中的工具调用。
type ToolCall struct {
	ID       string       `json:"id"`
	Type     string       `json:"type"`
	Function FunctionCall `json:"function"`
}

// FunctionCall 携带调用名与 JSON 编码的实参。
type FunctionCall struct {
	Name      string `json:"name"`
	Arguments string `json:"arguments"`
}

// ResponseFormat 对应 response_format(json_object / json_schema)。
type ResponseFormat struct {
	Type       string          `json:"type"`
	JSONSchema json.RawMessage `json:"json_schema,omitempty"`
}

// ChatResponse 是非流式响应体(chat.completion)。
type ChatResponse struct {
	ID      string   `json:"id"`
	Object  string   `json:"object"`
	Created int64    `json:"created"`
	Model   string   `json:"model"`
	Choices []Choice `json:"choices"`
	Usage   *Usage   `json:"usage,omitempty"`
}

// Choice 是一条候选回复。
type Choice struct {
	Index        int         `json:"index"`
	Message      ChatMessage `json:"message"`
	FinishReason string      `json:"finish_reason"`
}

// ChatChunk 是流式增量事件体(chat.completion.chunk)。
type ChatChunk struct {
	ID      string        `json:"id"`
	Object  string        `json:"object"`
	Created int64         `json:"created"`
	Model   string        `json:"model"`
	Choices []ChunkChoice `json:"choices"`
	Usage   *Usage        `json:"usage,omitempty"`
}

// ChunkChoice 是流式事件中的增量候选。
type ChunkChoice struct {
	Index        int     `json:"index"`
	Delta        Delta   `json:"delta"`
	FinishReason *string `json:"finish_reason"`
}

// Delta 是流式增量内容;Content 为纯文本片段。
type Delta struct {
	Role      string          `json:"role,omitempty"`
	Content   string          `json:"content,omitempty"`
	ToolCalls []ToolCallDelta `json:"tool_calls,omitempty"`
}

// ToolCallDelta 是工具调用的流式片段;Index 标识聚合目标。
type ToolCallDelta struct {
	Index    int               `json:"index"`
	ID       string            `json:"id,omitempty"`
	Type     string            `json:"type,omitempty"`
	Function FunctionCallDelta `json:"function"`
}

// FunctionCallDelta 是函数名 / 实参的增量片段。
type FunctionCallDelta struct {
	Name      string `json:"name,omitempty"`
	Arguments string `json:"arguments,omitempty"`
}
