package aiwire

import (
	"encoding/json"
	"strings"
)

// MessagesRequest 是 Anthropic /v1/messages 请求体。
type MessagesRequest struct {
	Model         string          `json:"model"`
	MaxTokens     int             `json:"max_tokens"`
	System        json.RawMessage `json:"system,omitempty"`
	Messages      []AnthMessage   `json:"messages"`
	StopSequences []string        `json:"stop_sequences,omitempty"`
	Temperature   *float64        `json:"temperature,omitempty"`
	TopP          *float64        `json:"top_p,omitempty"`
	TopK          *int            `json:"top_k,omitempty"`
	Stream        bool            `json:"stream,omitempty"`
	Tools         []AnthTool      `json:"tools,omitempty"`
	ToolChoice    json.RawMessage `json:"tool_choice,omitempty"`
	Metadata      json.RawMessage `json:"metadata,omitempty"`
	Thinking      json.RawMessage `json:"thinking,omitempty"`
	// OutputConfig 是 Anthropic 官方输出控制(effort 等);网关映射 effort 到 OCI reasoningEffort。
	OutputConfig *AnthOutputConfig `json:"output_config,omitempty"`
}

// AnthOutputConfig 是 Anthropic Messages 顶层 output_config 对象。
type AnthOutputConfig struct {
	Effort string `json:"effort,omitempty"`
}

// SystemText 把顶层 system(string 或块数组)拍平为文本。
func (r MessagesRequest) SystemText() string {
	if len(r.System) == 0 {
		return ""
	}
	var s string
	if err := json.Unmarshal(r.System, &s); err == nil {
		return s
	}
	var blocks []AnthBlock
	if err := json.Unmarshal(r.System, &blocks); err != nil {
		return ""
	}
	var sb strings.Builder
	for _, b := range blocks {
		if b.Type == "text" {
			sb.WriteString(b.Text)
		}
	}
	return sb.String()
}

// AnthMessage 是 Anthropic 消息;Content 兼容 string 与块数组。
type AnthMessage struct {
	Role    string      `json:"role"`
	Content AnthContent `json:"content"`
}

// AnthContent 是 string | []AnthBlock 联合。
type AnthContent struct {
	Text    string
	Blocks  []AnthBlock
	isArray bool
}

func (c *AnthContent) UnmarshalJSON(b []byte) error {
	trimmed := strings.TrimSpace(string(b))
	if trimmed == "null" {
		return nil
	}
	if len(trimmed) > 0 && trimmed[0] == '[' {
		c.isArray = true
		return json.Unmarshal(b, &c.Blocks)
	}
	return json.Unmarshal(b, &c.Text)
}

func (c AnthContent) MarshalJSON() ([]byte, error) {
	if c.isArray {
		return json.Marshal(c.Blocks)
	}
	return json.Marshal(c.Text)
}

// AllBlocks 统一为块数组视图(字符串形态包装为单 text 块)。
func (c AnthContent) AllBlocks() []AnthBlock {
	if c.isArray {
		return c.Blocks
	}
	if c.Text == "" {
		return nil
	}
	return []AnthBlock{{Type: "text", Text: c.Text}}
}

// AnthBlock 是内容块;按 Type 取字段(text / tool_use / tool_result / image / thinking)。
type AnthBlock struct {
	Type string `json:"type"`
	Text string `json:"text,omitempty"`
	// tool_use
	ID    string          `json:"id,omitempty"`
	Name  string          `json:"name,omitempty"`
	Input json.RawMessage `json:"input,omitempty"`
	// tool_result
	ToolUseID string          `json:"tool_use_id,omitempty"`
	Content   json.RawMessage `json:"content,omitempty"`
	IsError   bool            `json:"is_error,omitempty"`
	// image
	Source json.RawMessage `json:"source,omitempty"`
}

// ResultText 把 tool_result 的 content(string 或块数组)拍平为文本。
func (b AnthBlock) ResultText() string {
	if len(b.Content) == 0 {
		return ""
	}
	var s string
	if err := json.Unmarshal(b.Content, &s); err == nil {
		return s
	}
	var blocks []AnthBlock
	if err := json.Unmarshal(b.Content, &blocks); err != nil {
		return string(b.Content)
	}
	var sb strings.Builder
	for _, blk := range blocks {
		if blk.Type == "text" {
			sb.WriteString(blk.Text)
		}
	}
	return sb.String()
}

// AnthTool 是 Anthropic 工具定义(input_schema 即 JSON Schema)。
type AnthTool struct {
	Name        string          `json:"name"`
	Description string          `json:"description,omitempty"`
	InputSchema json.RawMessage `json:"input_schema,omitempty"`
}

// MessagesResponse 是非流式响应体。
type MessagesResponse struct {
	ID           string      `json:"id"`
	Type         string      `json:"type"`
	Role         string      `json:"role"`
	Model        string      `json:"model"`
	Content      []AnthBlock `json:"content"`
	StopReason   string      `json:"stop_reason"`
	StopSequence *string     `json:"stop_sequence"`
	Usage        AnthUsage   `json:"usage"`
}

// AnthUsage 是 Anthropic 用量结构。
type AnthUsage struct {
	InputTokens  int `json:"input_tokens"`
	OutputTokens int `json:"output_tokens"`
	// CacheReadInputTokens 是缓存命中读取数;OCI 隐式缓存无「写入」计数,cache_creation 恒缺
	CacheReadInputTokens int `json:"cache_read_input_tokens,omitempty"`
}

// AnthErrorBody 是 Anthropic 格式错误响应。
type AnthErrorBody struct {
	Type  string          `json:"type"`
	Error AnthErrorDetail `json:"error"`
}

// AnthErrorDetail 是错误明细。
type AnthErrorDetail struct {
	Type    string `json:"type"`
	Message string `json:"message"`
}
