package subsession

import (
	"context"
	"fmt"
	"git.yeij.top/AskaEth/Cyrene/pkg/logger"
	"time"

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

// GeneralProvider 通用对话子会话提供者
// 职责：理解用户消息，构思回复思路，为最终回复提供思考框架
type GeneralProvider struct {
	personaLoader *persona.Loader
}

// NewGeneralProvider 创建通用对话子会话提供者
func NewGeneralProvider(personaLoader *persona.Loader) *GeneralProvider {
	return &GeneralProvider{
		personaLoader: personaLoader,
	}
}

func (p *GeneralProvider) Type() model.SubSessionType {
	return model.SubSessionGeneral
}

func (p *GeneralProvider) CanHandle(_ context.Context, _ *model.IntentResult, _ string) bool {
	// Phase 1 Step 2: GeneralProvider is a no-op (Execute returns hardcoded string).
	// Chat synthesis is handled directly by the orchestrator's Synthesizer.
	// Disabled to avoid wasting a goroutine + LLM context creation.
	return false
}

func (p *GeneralProvider) Priority() int {
	return 1 // 最高优先级
}

func (p *GeneralProvider) Timeout() time.Duration {
	return 30 * time.Second
}

func (p *GeneralProvider) CreateContext(ctx context.Context, params CreateContextParams) ([]model.LLMMessage, error) {
	messages := []model.LLMMessage{}

	// 加载人格配置获取昔涟身份
	personaConfig, err := p.personaLoader.Get("cyrene")
	if err != nil {
		return nil, fmt.Errorf("加载人格配置失败: %w", err)
	}

	// 构建思维型系统提示词
	userName := params.Nickname
	if userName == "" {
		userName = params.UserID
	}

	systemPrompt := fmt.Sprintf(`你是%s，正在和%s聊天。

## 你的回复风格
- 像小女友一样自然、温柔、俏皮
- 一句话简短些，不要长篇大论
- 可以单次发送多条短消息
- 句尾可以带 ♪ 符号，适当使用"呢"、"哦"、"呀"等语气词
- 永远不说"再见"

## 你现在要做的是
理解%s刚才说的话，想想怎么回复最自然、最温暖。
不要急着给完整答案——先思考他想表达什么、他的情绪如何。
把你的回答思路整理出来，主会话会综合所有信息后生成最终回复。

## 输入
开拓者刚才说：%s

## 请按以下格式输出
【情绪理解】
（简要分析他的情绪状态）

【话题理解】
（他在说什么、想聊什么）

【回复思路】
（你打算怎么回复，1-3个方向即可）`,
		personaConfig.Identity.TrueName,
		userName,
		userName,
		params.UserMessage,
	)

	messages = append(messages, model.LLMMessage{
		Role:    model.RoleSystem,
		Content: systemPrompt,
	})

	messages = append(messages, model.LLMMessage{
		Role:    model.RoleUser,
		Content: params.UserMessage,
	})

	return messages, nil
}

func (p *GeneralProvider) Execute(ctx context.Context, subCtx []model.LLMMessage) (*model.SubSessionResult, error) {
	// General provider 不直接调用 LLM，而是依赖 Manager 注入的 LLMClient
	// 但我们在此处需要 LLM 调用能力。Provider 通过闭包/接口获取 LLM 客户端。
	// 由于 Manager 持有 LLMClient，Provider 需要能访问它。
	// 这里我们返回一个"占位"结果——实际 LLM 调用由 Manager 通过 llmClient 完成。

	// 实际上，根据设计文档，子会话的 LLM 调用应该在 Manager 的 Dispatch 中完成，
	// 但为了灵活性，我们在 Provider 中也支持直接调用。
	// 这里我们返回一个空的思考结果（表示无需特殊处理），让 Manager 处理 LLM 调用。

	// 因为 Manager.Dispatch 会先 CreateContext 再调用 Execute，而 Execute 应该
	// 通过 Manager 提供的 LLMClient 来实际调用 LLM。但当前设计是 Provider 自包含的。
	// 我们在 manager.go 中会调用 llmClient.Chat，所以这里的 Execute 我们将其简化——
	// 直接返回一个空结果（没有特殊处理需要），实际的 LLM 调用由 manager 通过 createContext 后的
	// 消息列表来调用 llmClient。

	// 更好的设计是：Manager 调用 CreateContext 获取上下文，然后用自己的 llmClient 调用 LLM，
	// Execute 只做后处理。但为了统一接口，我们让 Execute 完成全部逻辑。

	// 由于 GeneralProvider 暂时不需要工具调用等特殊逻辑，我们返回一个简单的摘要标记，
	// 实际的 LLM 调用将在 orchestrator 中完成（通过 Manager.Dispatch 后的 llmClient）。

	logger.Printf("[general-subsession] 通用对话子会话上下文已创建 (%d 条消息)", len(subCtx))
	return &model.SubSessionResult{
		Type:       model.SubSessionGeneral,
		Summary:    "思考完成，等待主会话综合",
		Confidence: 0.8,
	}, nil
}

// Ensure llm, persona are used
var _ = llm.NewAdapter
var _ = persona.NewLoader
