package biz

import (
	"ai_scheduler/internal/biz/do"
	"ai_scheduler/internal/config"
	"ai_scheduler/internal/data/constants"
	errors "ai_scheduler/internal/data/error"
	"ai_scheduler/internal/gateway"

	"ai_scheduler/internal/pkg/rec_extra"
	"context"
	"encoding/json"
	"strings"
	"time"

	"ai_scheduler/internal/entitys"

	"github.com/gofiber/fiber/v2/log"
)

// AiRouterBiz 智能路由服务
type AiRouterBiz struct {
	do     *do.Do
	handle *do.Handle
	config *config.Config
}

// NewAiRouterBiz 创建路由服务
func NewAiRouterBiz(
	do *do.Do,
	handle *do.Handle,
	config *config.Config,
) *AiRouterBiz {
	return &AiRouterBiz{
		do:     do,
		handle: handle,
		config: config,
	}
}

//	路由处理WebSocket请求
//
// 参数:
//   - client: 网关客户端
//   - req: 聊天请求结构体
//
// 返回:
//   - err: 错误信息
func (r *AiRouterBiz) RouteWithSocket(client *gateway.Client, req *entitys.ChatSockRequest) (err error) {
	// 创建请求上下文数据
	requireData := &entitys.RequireData{
		Req: req,
	}

	//初始化通道/上下文
	ctx, clearFunc := r.do.MakeCh(client, requireData)
	defer func() {
		if err != nil {
			entitys.ResError(requireData.Ch, "", err.Error())
		}
		clearFunc()
	}()

	//数据验证和收集
	if err = r.do.DataAuth(ctx, client, requireData); err != nil {
		log.Errorf("数据验证和收集失败: %s", err.Error())
		return
	}
	//组装意图识别
	rec, sys, err := r.SetRec(ctx, requireData)
	if err != nil {
		log.Errorf("组装意图识别失败: %s", err.Error())
		return
	}
	//意图识别

	err = r.handle.Recognize(ctx, &rec, sys)
	if err != nil {
		log.Errorf("意图识别失败: %s", err.Error())
		return
	}
	//任务处理
	rec_extra.SetTaskRecExt(requireData, &rec)
	//向下传递
	if err = r.handle.HandleMatch(ctx, client, &rec, requireData); err != nil {
		log.Errorf("任务处理失败: %s", err.Error())
		return
	}
	return
}

func (r *AiRouterBiz) SetRec(ctx context.Context, requireData *entitys.RequireData) (match entitys.Recognize, sys do.PromptOption, err error) {
	// 参数空值检查
	if requireData == nil || requireData.Req == nil {
		return match, sys, errors.NewBusinessErr(500, "请求参数为空")
	}

	// 对应不同的appKey, 配置不同的系统提示词
	switch requireData.Sys.AppKey {
	default:
		sys = &do.WithSys{Config: r.config}
	}

	// 1. 系统提示词
	match.SystemPrompt = requireData.Sys.SysPrompt

	// 2. 用户输入和文件处理
	match.UserContent, err = r.buildUserContent(requireData)
	if err != nil {
		log.Errorf("构建用户内容失败: %s", err.Error())
		return
	}

	// 3. 聊天记录 - 只有在有历史记录时才构建
	if len(requireData.Histories) > 0 {
		match.ChatHis = r.buildChatHistory(requireData)
	}

	// 4. 任务列表 - 预分配切片容量
	if len(requireData.Tasks) > 0 {
		match.Tasks = make([]entitys.RegistrationTask, 0, len(requireData.Tasks))
		for _, task := range requireData.Tasks {
			taskConfig := entitys.TaskConfigDetail{}
			if err = json.Unmarshal([]byte(task.Config), &taskConfig); err != nil {
				log.Errorf("解析任务配置失败: %s, 任务ID: %s", err.Error(), task.Index)
				continue // 解析失败时跳过该任务，而不是直接返回错误
			}

			match.Tasks = append(match.Tasks, entitys.RegistrationTask{
				Name:             task.Index,
				Desc:             task.Desc,
				TaskConfigDetail: taskConfig, // 直接使用解析后的配置，避免重复构建
			})
		}
	}

	match.Ch = requireData.Ch
	return
}

// buildUserContent 构建用户内容
func (r *AiRouterBiz) buildUserContent(requireData *entitys.RequireData) (*entitys.RecognizeUserContent, error) {
	// 预分配文件切片容量（最多2个文件：File和Img）
	files := make([]*entitys.RecognizeFile, 0, 2)

	// 处理文件和图片
	fileUrls := []string{requireData.Req.File, requireData.Req.Img}
	for _, item := range fileUrls {
		// 处理逗号分隔的多个URL
		urlList := strings.Split(item, ",")
		for _, url := range urlList {
			if url != "" {
				files = append(files, &entitys.RecognizeFile{FileUrl: url})
			}
		}
	}

	// 构建并返回用户内容
	return &entitys.RecognizeUserContent{
		Text:          requireData.Req.Text,
		File:          files,
		ActionCardUrl: "", // TODO: 后续实现操作卡片功能
		Tag:           requireData.Req.Tags,
	}, nil
}

// buildChatHistory 构建聊天历史
func (r *AiRouterBiz) buildChatHistory(requireData *entitys.RequireData) entitys.ChatHis {
	// 预分配消息切片容量（每个历史记录生成2条消息）
	messages := make([]entitys.HisMessage, 0, len(requireData.Histories)*2)

	// 构建聊天记录
	for _, h := range requireData.Histories {
		// 用户消息
		messages = append(messages, entitys.HisMessage{
			Role:      constants.RoleUser, // 用户角色
			Content:   h.Ques,             // 用户输入内容
			Timestamp: h.CreateAt.Format(time.DateTime),
		})

		// 助手消息 - 助手回复噪音太大且无需，pass
		// ansStr := r.ansNoiseReduction(h.Ans) // 助手回复降噪
		// messages = append(messages, entitys.HisMessage{
		// 	Role:      constants.RoleAssistant, // 助手角色
		// 	Content:   ansStr,                  // 助手回复内容
		// 	Timestamp: h.CreateAt.Format(time.DateTime),
		// })
	}

	// 构建聊天历史上下文
	return entitys.ChatHis{
		SessionId: requireData.Session,
		Messages:  messages,
		Context: entitys.HisContext{
			UserLanguage: constants.LangZhCN,                   // 默认中文
			SystemMode:   constants.SystemModeTechnicalSupport, // 默认技术支持模式
		},
	}
}

// ansNoiseReduction 助手回复降噪
// func (r *AiRouterBiz) ansNoiseReduction(ansJson string) string {
// 	// 使用anw统一类型解析
// 	ansStruct := make([]*entitys.Response, 0)
// 	err := json.Unmarshal([]byte(ansJson), &ansStruct)
// 	if err != nil {
// 		log.Errorf("解析助手回复失败: %s", err.Error())
// 		return ansJson
// 	}
// 	var ansStr string
// 	for _, item := range ansStruct {
// 		ansStr += item.Content
// 	}

// 	return ansStr
// }
