package eino

import (
	"context"
	"strings"
	"testing"

	"github.com/cloudwego/eino/schema"

	"github.com/sundynix/sundynix-shared/contract"
)

// TestBuildMessagesShape 锁定 ChatTemplate 产出的消息序列与旧手拼逻辑等价：
// [system(含画像+参考资料)] + [历史...] + [user(query)]，且 JSON 花括号不被误解析。
func TestBuildMessagesShape(t *testing.T) {
	rc := &RunCtx{
		System:  "你是助手",
		Query:   "今天几号",
		Profile: "称呼=Dexter",
		History: []*schema.Message{schema.UserMessage("上一句"), schema.AssistantMessage("上一答", nil)},
		ToolOut: []string{`{"k":"v"}`}, // 含花括号，验证 FString 不误解析
	}
	msgs, err := buildMessages(context.Background(), rc)
	if err != nil {
		t.Fatal(err)
	}
	if len(msgs) != 4 {
		t.Fatalf("应为 system+2历史+user=4 条，实际 %d", len(msgs))
	}
	if msgs[0].Role != schema.System || !strings.Contains(msgs[0].Content, "你是助手") ||
		!strings.Contains(msgs[0].Content, "称呼=Dexter") || !strings.Contains(msgs[0].Content, `{"k":"v"}`) {
		t.Fatalf("system 消息不对: %q", msgs[0].Content)
	}
	if msgs[3].Role != schema.User || msgs[3].Content != "今天几号" {
		t.Fatalf("user 消息不对: %q", msgs[3].Content)
	}
}

// fakeCaller 是 ToolCaller 测试替身，固定返回 kb_search 命中。
type fakeCaller struct{ content string }

func (f *fakeCaller) CallTool(_ context.Context, _ string, _ *contract.ToolCall) (*contract.ToolResult, error) {
	return &contract.ToolResult{OK: true, Content: f.content}, nil
}

// TestRagRetrieverComponent 验证 Retriever 组件把 kb_search 命中转成 *schema.Document。
func TestRagRetrieverComponent(t *testing.T) {
	o := &Orchestrator{tools: &fakeCaller{content: `[{"text":"片段A","score":0.9},{"text":"片段B","score":0.8}]`}}
	docs, err := o.newRetriever("u/kb").Retrieve(context.Background(), "q")
	if err != nil {
		t.Fatal(err)
	}
	if len(docs) != 2 || docs[0].Content != "片段A" || docs[1].Content != "片段B" {
		t.Fatalf("文档解析不对: %+v", docs)
	}
}
