package agent

import (
	"context"
	"encoding/json"
	"io"
	"strings"

	"github.com/cloudwego/eino-ext/components/model/ark"
	"github.com/cloudwego/eino/schema"
)

// StreamResponse 专为 Apifox/前端 识别设计的极简结构
type StreamResponse struct {
	Choices []struct {
		Delta struct {
			Content string `json:"content"`
		} `json:"delta"`
	} `json:"choices"`
}

// ToStreamResponseDTO 将 Eino 的内部 Chunk 转换为 StreamResponse DTO
func ToStreamResponseDTO(chunk *schema.Message) StreamResponse {
	var dto StreamResponse
	dto.Choices = append(dto.Choices, struct {
		Delta struct {
			Content string `json:"content"`
		} `json:"delta"`
	}{})
	dto.Choices[0].Delta.Content = chunk.Content
	return dto
}

// ToOpenAIStream 负责将 Eino 的内部 Chunk 转换为 OpenAI 兼容的 data: {JSON} 字符串
func ToOpenAIStream(chunk *schema.Message) (string, error) {
	dto := ToStreamResponseDTO(chunk)

	jsonBytes, err := json.Marshal(dto)
	if err != nil {
		return "", err
	}
	// 严格遵循 SSE 协议格式
	return string(jsonBytes), nil
}

func StreamChat(ctx context.Context, llm *ark.ChatModel, userInput string, chatHistory []*schema.Message, outChan chan<- string) (string, error) {
	// 1. 组装消息
	messages := make([]*schema.Message, 0)
	// A. 塞入 System Message (人设)
	messages = append(messages, schema.SystemMessage(SystemPrompt))
	// B. 塞入历史记录 (上下文)
	if len(chatHistory) > 0 {
		messages = append(messages, chatHistory...)
	}
	// C. 塞入用户当前的消息 (当前需求)
	messages = append(messages, schema.UserMessage(userInput))
	// 2. 调用流式接口
	reader, err := llm.Stream(ctx, messages)
	if err != nil {
		return "", err
	}
	defer reader.Close() // 记得关闭 Reader

	// 3. 循环读取直到结束
	var fullText strings.Builder
	for {
		chunk, err := reader.Recv()
		if err == io.EOF {
			break // 读取完成
		}
		if err != nil {
			return "", err
		}
		if chunk.Content == "" {
			continue
		}
		fullText.WriteString(chunk.Content)
		// 将内容发送到通道中供前端消费
		retChuck, err := ToOpenAIStream(chunk)
		if err != nil {
			return "", err
		}
		outChan <- retChuck
	}
	return fullText.String(), nil
}
