package llm

import (
	"context"
	"io"

	"git.yeij.top/AskaEth/Cyrene/ai-core/internal/model"
)

// Adapter LLM适配器接口
// 支持不同的LLM后端（OpenAI、Ollama、vLLM等）
type Adapter struct {
	provider LLMProvider
}

// OpenAITool 暴露给调用方使用的工具定义（与 openai.go 的 openAITool 等价）
type OpenAITool struct {
	Type     string         `json:"type"`
	Function OpenAIToolFunc `json:"function"`
}

// OpenAIToolFunc 工具函数定义
type OpenAIToolFunc struct {
	Name        string                 `json:"name"`
	Description string                 `json:"description"`
	Parameters  map[string]interface{} `json:"parameters"`
}

// LLMProvider LLM提供商接口
type LLMProvider interface {
	// Chat 同步对话
	Chat(ctx context.Context, messages []model.LLMMessage) (*model.LLMResponse, error)

	// ChatStream 流式对话，返回一个channel逐token推送
	ChatStream(ctx context.Context, messages []model.LLMMessage) (<-chan StreamChunk, error)

	// ChatWithTools 同步对话（支持工具调用），tools 为 nil 时等价于 Chat
	ChatWithTools(ctx context.Context, messages []model.LLMMessage, tools []OpenAITool) (*model.LLMResponse, error)

	// ChatStreamWithTools 流式对话（支持工具调用），tools 为 nil 时等价于 ChatStream
	ChatStreamWithTools(ctx context.Context, messages []model.LLMMessage, tools []OpenAITool) (<-chan StreamChunk, error)

	// ModelName 返回当前使用的模型名称
	ModelName() string
}

// StreamChunk 流式响应的单个片段
type StreamChunk struct {
	Content string      // delta内容
	Done    bool        // 是否为最后一块
	Error   error       // 错误信息
	Usage   *model.Usage // 最后一块时返回token统计
}

// NewAdapter 创建LLM适配器
func NewAdapter(provider LLMProvider) *Adapter {
	return &Adapter{provider: provider}
}

// Chat 同步对话
func (a *Adapter) Chat(ctx context.Context, messages []model.LLMMessage) (*model.LLMResponse, error) {
	return a.provider.Chat(ctx, messages)
}

// ChatWithTools 同步对话（支持工具调用）
func (a *Adapter) ChatWithTools(ctx context.Context, messages []model.LLMMessage, tools []OpenAITool) (*model.LLMResponse, error) {
	return a.provider.ChatWithTools(ctx, messages, tools)
}

// ChatStream 流式对话
func (a *Adapter) ChatStream(ctx context.Context, messages []model.LLMMessage) (<-chan StreamChunk, error) {
	return a.provider.ChatStream(ctx, messages)
}

// ChatStreamWithTools 流式对话（支持工具调用）
func (a *Adapter) ChatStreamWithTools(ctx context.Context, messages []model.LLMMessage, tools []OpenAITool) (<-chan StreamChunk, error) {
	return a.provider.ChatStreamWithTools(ctx, messages, tools)
}

// ModelName 返回模型名称
func (a *Adapter) ModelName() string {
	return a.provider.ModelName()
}

// collectStream 辅助函数：将流式响应收集为完整响应
func collectStream(ch <-chan StreamChunk) (*model.LLMResponse, error) {
	var content string
	var lastUsage *model.Usage

	for chunk := range ch {
		if chunk.Error != nil {
			return nil, chunk.Error
		}
		if chunk.Done {
			lastUsage = chunk.Usage
			break
		}
		content += chunk.Content
	}

	resp := &model.LLMResponse{
		Content:      content,
		FinishReason: "stop",
	}
	if lastUsage != nil {
		resp.Usage = *lastUsage
	}
	return resp, nil
}

// Ensure io is used (will be needed for SSE parsing)
var _ io.Reader
