package service

import (
	"WorldEpcho/src/config"
	"WorldEpcho/src/config/e"
	"WorldEpcho/src/datasource"
	"WorldEpcho/src/models"
	"WorldEpcho/src/utils"
	"encoding/json"
	"fmt"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
)

//const month = 60 * 60 * 24 * 30 // 按照30天算一个月

// 发送消息的类型
type WorldSendMsg struct {
	Type    int    `json:"type"`
	Content string `json:"content"`
}

// 回复的消息
/* 这个要注释掉 */
type WorldReplyMsg struct {
	From       string `json:"from"`
	Code       int    `json:"code"`
	Content    string `json:"content"`
	StatusCode int    `json:"statusCode,omitempty"`
}

// 转发AI接口意识流响应给前端
type WorldSoulReplyMsg struct {
	Code              int                    `json:"code"`
	WObj              map[string]interface{} `json:"WObj"`
	ISLIU             string                 `json:"ISLIU"`
	WorldName         string                 `json:"WorldName"`
	IsLIUId           *string                `json:"IsLIUId,omitempty"`           // 使用指针类型，并添加 omitempty 标签,可选字段
	MessageStatusType string                 `json:"messageStatusType,omitempty"` // Optional field to indicate message type
}

/*
构建Client表
*/
type WorldClient struct {
	//DpConversations *models.DpConversations
	WorldConversations *models.WorldConversation
	Socket             *websocket.Conn
	Send               chan *WorldEchoResponse
	WorldName          string
	AuthId             string
	UserSource         string
}

// 用户类
/*
type Client struct {
	Id     string
	SendID string
	Socket *websocket.Conn
	Send   chan []byte
}
*/

// 广播类，包括广播内容和源用户
/*
type Broadcast struct {
	Client  *Client
	Message []byte
	Type    int
}
*/

// 用户管理
type WorldClientManager struct {
	Client map[string]*WorldClient
	//Broadcast  chan *Broadcast
	Reply      chan *WorldClient
	Register   chan *WorldClient
	Unregister chan *WorldClient
}

// Message 信息转JSON (包括：发送者、接收者、内容)
type WorldMessage struct {
	Sender    string `json:"sender,omitempty"`
	Recipient string `json:"recipient,omitempty"`
	Content   string `json:"content,omitempty"`
}

var WorldManager = WorldClientManager{
	Client: make(map[string]*WorldClient), // 参与连接的用户，出于性能的考虑，需要设置最大连接数
	//Broadcast:  make(chan *Broadcast),
	Register:   make(chan *WorldClient),
	Reply:      make(chan *WorldClient),
	Unregister: make(chan *WorldClient),
}

//错误消息响应结构体
type WorldErrorMessage struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

// Wrapper 结构体仅包含一个字符串字段，用于存储 JSON 字符串
type Wrapper struct {
	ConfigData map[string]interface{} `json:"ConfigData"`
}

func WorldWsHandler(ctx *gin.Context) {
	/*
	 http协议升级为webSocket协议
	*/
	conn, err := (&websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool { // CheckOrigin解决跨域问题
			return true
		}}).Upgrade(ctx.Writer, ctx.Request, nil) // 升级成ws协议

	if err != nil {
		http.NotFound(ctx.Writer, ctx.Request)
		return
	}
	/*
	   从session里获取用户id
	*/
	session := sessions.Default(ctx)
	userId := session.Get("WorldUserID")
	if userId == nil {
		// 处理session中未找到值的情况，返回错误信息
		/*这里是双保险为了测试用*/
		userId = ctx.Query("uid")
		if userId == nil {
			ctx.JSON(http.StatusOK, gin.H{"code": e.NotLoginUser, "data": nil, "message": "Session中未找到用户ID,用户未登录"})
			fmt.Println(config.ColorYellow, "Session中未找到用户ID,用户未登录", config.ColorReset)
			return
		}
	}
	fmt.Println("world chat session UserID：", userId)
	var SP *models.ServiceProvider
	// 服务商id获取
	//从配置文件读取咪咕服务商ID
	miGuAuthId := config.Conf.MiGuAuthId

	ServiceProviderId := ctx.Query("AuthId")
	if ServiceProviderId != "" || ServiceProviderId == miGuAuthId {
		// 从请求头中获取 JWT token
		tokenString := ctx.GetHeader("Token")
		if tokenString == "" {
			fmt.Printf("no Authorization token provided")
			ctx.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "请求头中无token信息!"})
			return
		}
		isValid, err := IsValidMiGuToken(tokenString)
		if err != nil {
			ctx.JSON(http.StatusOK, gin.H{"code": e.TokenAuthError, "data": nil, "message": "解析token出错!"})
			return
		}
		if !isValid {
			ctx.JSON(http.StatusOK, gin.H{"code": e.InvalidToken, "data": nil, "message": "无效的token"})
			return
		}

		SP, err = models.GetServiceProviderById(ServiceProviderId)
		if err != nil {
			fmt.Println("根据服务商id查询出错:", err)
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "data": nil, "message": "根据服务商id查询服务商出错"})
			return
		}
		if SP == nil {
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "data": nil, "message": "非法的服务商"})
			return
		}
	}
	user_Id, ok := userId.(string)
	if !ok {
		// 类型断言失败，处理类型不匹配的情况
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "data": nil, "message": "用户ID类型错误"})
		return
	}
	//userId作为string类型的值进行后续操作
	_, b := config.WorldLoginCacheCode.Get(user_Id)

	uid, err := strconv.ParseInt(user_Id, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "data": nil, "message": "数字人id类型转换出错"})
		//continue
		return
	}
	if user_Id == "" && ServiceProviderId == "" {
		fmt.Println(config.ColorPurple, "用户id或者服务商id为空", config.ColorReset)
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "data": nil, "message": "用户id或者服务商id为空"})
		return
	}
	if SP != nil {
		if SP.InspirationValue == 0 {
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "data": nil, "message": "服务商的灵感值余额不足，无法进行数字人聊天"})
			return
		}
	}

	//校验用户是不是服务商那边的用户
	if user_Id != "" && SP != nil {
		user, err := models.GetUserByID(uid)
		if err != nil {
			fmt.Println(config.ColorPurple, "根据用户ID查询用户信息出错", config.ColorReset)
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "根据用户ID查询用户信息出错"})
			return
		}
		if user.RegisteredSource != SP.Name {
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": " 该用户不是服务商的用户不能连接! "})
			fmt.Println("该用户不是服务商的用户不能连接!")
			return
		}

	}
	/*
	   判断用户是否登录
	*/
	//定义会话主题
	//var ConversationTitle string
	worldName := ctx.Query("world_name")
	world_Id := ctx.Query("worldId")
	var world *models.WorldInfo
	var userInfo string

	if worldName != "" {
		world, err = models.GetWorldInfoByName(worldName)
		if err != nil {
			log.Println("根据世界名称，查询世界信息失败")
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "根据世界名称，查询世界信息失败"})
			return
		}
	}
	if world_Id != "" {
		worldId, err := strconv.ParseInt(world_Id, 10, 64)
		if err != nil {
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "世界ID类型转换出错"})

			return
		}
		world, _, err = models.GetWorldInfoById(worldId)
		if err != nil {
			log.Println("根据世界名称，查询世界信息失败")
			ctx.JSON(http.StatusOK, gin.H{"code": e.ErrorDatabase, "data": nil, "message": "根据世界名称，查询世界信息失败"})
			return
		}
		if world == nil {
			log.Println("世界信息不存在")
			ctx.JSON(http.StatusOK, gin.H{"code": e.NotFound, "data": nil, "message": "世界信息不存在"})
			return
		}
	}

	if world == nil {
		log.Println("世界名称不存在")
		ctx.JSON(http.StatusOK, gin.H{"code": e.NotFound, "data": nil, "message": "世界名称不存在"})
		return
	}

	if b || SP != nil {
		fmt.Println("ServiceProvider ===> ", SP)
		BgInfo := ctx.Query("BgInfo")
		user_info := ctx.Query("userInfo")
		if user_info != "" {
			userInfo = user_info
		}
		//拼接会话主题
		//ConversationTitle = "用户Id为" + user_Id + "的用户和数字人" + strings.Join(DpNames, "和") + "开始会话"
		//fmt.Println("ConversationTitle: ", ConversationTitle)
		if SP != nil && world != nil {
			if BgInfo == "" {
				BgInfo = world.Background
			}
			if user_info == "" {
				// 创建 Wrapper 实例并将 JSON 字符串封装

				wrapper := Wrapper{ConfigData: make(map[string]interface{})}
				// 将 JSON 字符串解析为 map[string]interface{}
				err := json.Unmarshal([]byte(world.ConfigData), &wrapper.ConfigData)
				if err != nil {
					log.Printf("Error parsing JSON: %v", err)
					return
				}

				// 打印解析后的数据
				//fmt.Printf("Wrapper ConfigData: %+v\n", wrapper.ConfigData)

				// 序列化 Wrapper 实例以生成所需的最终 JSON 输出
				finalJSON, err := json.Marshal(wrapper)
				if err != nil {
					fmt.Println("Error marshaling final JSON: ", err)
					ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "业务经理考核系统配置信息解析失败"})
					return
				}

				fmt.Println("ConfigData ===>", string(finalJSON))
				//userInfo = string(finalJSON)
				userInfo = string(finalJSON)
			}

		}

		worldConversation, _, err := models.GetWorldConversationByUidAndWorldName(uid, world.Name)
		if err != nil {
			log.Println("查询世界信息失败")
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "查询世界信息失败"})
			return
		}

		ISULU_ID := ""
		var world_response WorldCreateResponse
		var isNewHuaSoul bool
		if worldConversation == nil {
			//世界意识流不存在调用new接口创建
			world, new_conversation, err := CreateVirtualWorldHandler(uid, world.Name, BgInfo, userInfo)
			if err != nil {
				ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "创建世界失败！"})
				return
			}
			// 把新创建的世界会话赋值给会话对象
			worldConversation = new_conversation
			isNewHuaSoul = true
			ISULU_ID = world.ISLIUid
			world_response.Code = world.Code
			world_response.ISLIUid = world.ISLIUid
			world_response.WObj = world.WObj
			world_response.ISLIU = world.ISLIU
			//这里加了一个消息状态类型
			world_response.MessageStatusType = world.MessageStatusType
		} else {
			ISULU_ID = worldConversation.IsLiuId
			isNewHuaSoul = false
			// 如果查询到记录，调用查询意识流Id接口判断意识流id是否有效，若无效则修改意识流ID为新的意识流ID
			flag, err := FindWorldISLIU(uid, world.Name)
			if err != nil {
				ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "查询世界意识流id失败！"})
				return
			}
			fmt.Println("查询世界意识流Id, flag: ", flag)
			//没找到
			if !flag {
				//调用new接口创建世界
				world, new_conversation, err := CreateVirtualWorldHandler(uid, world.Name, BgInfo, userInfo)
				if err != nil {
					ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "创建世界失败！"})
					return
				}
				// 把新创建的世界会话赋值给会话对象
				worldConversation = new_conversation
				isNewHuaSoul = true
				ISULU_ID = world.ISLIUid
				world_response.Code = world.Code
				world_response.ISLIUid = world.ISLIUid
				world_response.WObj = world.WObj
				world_response.ISLIU = world.ISLIU
				//这里加了一个消息状态类型
				world_response.MessageStatusType = world.MessageStatusType
			}

		}
		//根据uid查询用户来源是否为咪咕
		user, err := models.GetUserByID(worldConversation.Uid)
		if err != nil {
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "根据用户id查询用户出错！"})
			return
		}
		// 创建一个用户客户端会话实例
		newClient := &WorldClient{
			WorldConversations: worldConversation,
			WorldName:          world.Name,
			Socket:             conn,
			Send:               nil,
			AuthId:             ServiceProviderId,
		}

		if user != nil && user.RegisteredSource != "" {
			newClient.UserSource = user.RegisteredSource
		}

		// 用户会话注册到用户管理上
		WorldManager.Register <- newClient

		if isNewHuaSoul {
			//  注册成功后，把世界信息开场白写入Socket
			if world_response.ISLIU == "" || world_response.WObj == nil {
				log.Println("世界开场白，意识流为空...")
				// 向前端返回数据格式不正确的状态码和消息
				errorMsg := WorldErrorMessage{
					Code:    -1,
					Message: "世界开场白，意识流为空...",
				}
				errmsg, _ := json.Marshal(errorMsg)
				_ = newClient.Socket.WriteMessage(websocket.TextMessage, errmsg)
				fmt.Println("返回世界开场白信息失败: ", errmsg)
				return

			}
			/* 创建响应体 */
			HSReplyMsg := WorldSoulReplyMsg{
				Code:      world_response.Code,
				WObj:      world_response.WObj,
				ISLIU:     world_response.ISLIU,
				WorldName: world.Name,
				//加了一个消息状态类型
				IsLIUId:           &world_response.ISLIUid,
				MessageStatusType: world_response.MessageStatusType,
			}

			msg, _ := json.Marshal(HSReplyMsg)
			write_err := newClient.Socket.WriteMessage(websocket.TextMessage, msg)
			if write_err != nil {
				log.Println("返回意识流给客户端时出错! ")
				WorldDestroyWs(newClient)
				return
			}
			/* 保存世界的独白到数据库 */
			senderType := "world"
			// 拼接会话Id
			conversation_Id := utils.Strval(newClient.WorldConversations.Uid) + "_" + utils.Strval(newClient.WorldConversations.WorldId)
			_, chatDB_err := datasource.SaveWorldChatRecordMongoDB(conversation_Id, newClient.WorldConversations.WorldId, newClient.WorldConversations.WorldName, world_response.ISLIU, world_response.WObj, senderType)
			// 错误处理
			if chatDB_err != nil {
				log.Println(config.ColorRed, "保存数字人聊天记录至数据库出错!", config.ColorReset)

				errorMsg := ErrorMessage{
					Code:    -1,
					Message: "保存数字人聊天记录至数据库出错！",
				}
				errmsg, _ := json.Marshal(errorMsg)
				_ = newClient.Socket.WriteMessage(websocket.TextMessage, errmsg)

				return
			}

		}

		// ------------------上传意识流---------------------- //

		url := config.Conf.SoulUrl + "/world/neural"

		fileName := "./neural/" + ISULU_ID + ".CFN"
		// 获取文件信息
		_, err = os.Stat(fileName)
		if err == nil {
			fmt.Println("文件存在")
			// 构造请求参数
			request := SoulNeuralRequest{
				Auth:    config.Conf.SoulAuth,
				Type:    1, // 1表示上载
				ISLIUid: ISULU_ID,
			}
			// 调用函数
			_, err := SoulNeuralFileUpload(url, request, fileName)
			if err != nil {
				log.Printf("Error during soul neural transfer: %v", err)
			}
			// 处理响应
			//fmt.Println("Response received: ", response)

		} else if os.IsNotExist(err) {
			fmt.Println("文件不存在")
		} else {
			fmt.Println("获取文件信息出错:", err)
		}

		// ---------------------------------------- //
		//fmt.Println("调用socket的Read方法前：", ISULU_ID)
		go newClient.WorldRead()
		//go newClient.WorldWrite()

	} else {
		ctx.JSON(http.StatusOK, gin.H{"code": e.NotLoginUser, "data": nil, "message": "用户未登录"})
		return
	}

}

func WorldDestroyWs(c *WorldClient) { // 避免忘记关闭，所以要加上close

	//关闭websocket之前，下载关于数字人的神经网络记忆文件
	url := config.Conf.SoulUrl + "/world/neural"
	fileName := "./neural/" + c.WorldConversations.IsLiuId + ".CFN"

	// 构造请求参数
	request := SoulNeuralRequest{
		Auth:    config.Conf.SoulAuth,
		Type:    0, // 0表示下载
		ISLIUid: c.WorldConversations.IsLiuId,
	}
	// 调用函数
	err1 := SoulNeuralFileDownload(url, request, fileName)
	if err1 != nil {
		log.Printf("Error during soul neural transfer: %v", err1)
	}
	//注销websocket的客户端
	WorldManager.Unregister <- c
	_ = c.Socket.Close()
	c.Socket = nil

}

/*
 从websocket读取客户端用户的消息，然后服务器回应前端一个消息
*/
func (c *WorldClient) WorldRead() {
	//从配置文件读取咪咕服务商ID
	miGuAuthId := config.Conf.MiGuAuthId
	//延迟关闭websocket
	defer WorldDestroyWs(c)
	/*
	  死循环执行websocket消息接收和发送
	*/
	for {
		c.Socket.PongHandler()
		sendMsg := new(WorldSendMsg)
		err := c.Socket.ReadJSON(&sendMsg)
		if err != nil {
			log.Println("数据格式不正确", err)
			// 向前端返回数据格式不正确的状态码和消息
			errorMsg := WorldErrorMessage{
				Code:    -1,
				Message: "数据格式不正确",
			}
			errmsg, errMarshal := json.Marshal(errorMsg)
			if errMarshal != nil {
				// 如果JSON编码失败，则打印错误消息
				log.Printf("JSON编码错误: %s\n", errMarshal)

			} else {
				// 发送错误消息
				errWrite := c.Socket.WriteMessage(websocket.TextMessage, errmsg)
				if errWrite != nil {
					// 如果WebSocket发送失败，则打印错误消息
					log.Printf("WebSocket发送错误: %s\n", errWrite)

				}
			}
			//fmt.Println("errmsg: ", errmsg)

			//剔除注册的客户端用户
			WorldManager.Unregister <- c
			fmt.Println(" Socket.Close() ... ")
			//关闭webSocket
			_ = c.Socket.Close()

			break
		}
		//打印前端发送过来的消息
		sendMsgMarshal, err := json.Marshal(sendMsg)
		if err != nil {
			// 打印错误信息的字符串表示
			log.Printf("Error marshaling sendMsg to JSON: %s", err.Error())
			// 在这里还可以做其它错误处理，例如返回一个错误响应等
		} else {
			// 打印 sendMsg JSON 字符串
			fmt.Printf("【==== sendMsg ===】 : %s\n", string(sendMsgMarshal))

			// 在这里可以继续处理 sendMsg JSON 字符串，比如发送它
		}

		/*

		 */
		go func() {
			/*
			   响应类型0 交互
			*/
			// 拼接会话Id
			conversation_Id := utils.Strval(c.WorldConversations.Uid) + "_" + utils.Strval(c.WorldConversations.WorldId)
			/*		dpIdsStr := utils.Int64SliceToStringSlice(c.DpConversations.DpIds)
					conversation_Id := utils.Strval(c.DpConversations.Uid) + "_" + strings.Join(dpIdsStr, ",") + "_" + utils.Strval(c.DpConversations.AppId)*/

			// 调用AI的会话接口
			echoResponse, chat_err := c.WorldEchoAPI(sendMsg)
			if c.Socket == nil {
				return
			}
			if chat_err != nil {
				log.Println("会话失败")
				// 向前端返回数据格式不正确的状态码和消息
				errorMsg := WorldErrorMessage{
					Code:    -1,
					Message: "会话失败",
				}

				// 将错误消息对象转换为 JSON 字符串
				errmsg, errMarshal := json.Marshal(errorMsg)
				if errMarshal != nil {
					// 如果 JSON 编码失败，则打印错误
					log.Printf("WorldEchoAPI error: %v", errMarshal)
				} else {
					// 发送错误消息
					errWrite := c.Socket.WriteMessage(websocket.TextMessage, errmsg)
					if errWrite != nil {
						//如果发送 WebSocket消息失败，则打印错误
						log.Printf("Error writing websocket message: %v", errWrite)
					}
				}
				// 删除会话记录
				/*		if chat_err.Error() == "调用会话接口失败无法获取意识流" {
							dropConversationErr := models.DeleteConversation()
							if dropConversationErr != nil {
								log.Println("删除会话失败")

							}

						}
				*/
				return
			}

			resCode := echoResponse.Code
			Wobj := echoResponse.WObj
			ISLIU := echoResponse.ISLIU

			if ISLIU == "" || Wobj == nil {
				log.Println("会话意识流为空...")
				// 向前端返回数据格式不正确的状态码和消息
				errorMsg := WorldErrorMessage{
					Code:    -1,
					Message: "会话意识流为空...",
				}
				errmsg, _ := json.Marshal(errorMsg)
				_ = c.Socket.WriteMessage(websocket.TextMessage, errmsg)

				fmt.Println("AI echo error: ", errmsg)
				return

			}
			// 读取前端发送过来的消息并打印
			fmt.Println("客户端消息: ", sendMsg)

			if sendMsg.Type == 0 {
				/*
				   收到前端发送过来的消息，保存至数据库
				*/
				senderType := "user"
				user_status := make(map[string]interface{})
				_, chatDB_err := datasource.SaveWorldChatRecordMongoDB(conversation_Id, c.WorldConversations.Uid, c.WorldConversations.WorldName, sendMsg.Content, user_status, senderType)
				// 错误处理
				if chatDB_err != nil {
					log.Println("保存用户聊天记录至数据库出错！")

					errorMsg := ErrorMessage{
						Code:    -1,
						Message: "保存用户聊天记录至数据库出错！",
					}
					errmsg, _ := json.Marshal(errorMsg)
					_ = c.Socket.WriteMessage(websocket.TextMessage, errmsg)

					return
				}
				/*
				   调用AI模型接口回复前端用户的消息
				*/
				HSReplyMsg := WorldSoulReplyMsg{
					Code:      resCode,
					WObj:      Wobj,
					ISLIU:     ISLIU,
					WorldName: c.WorldName,
					IsLIUId:   &c.WorldConversations.IsLiuId,
				}

				//判断是不是咪咕服务商
				if c.AuthId == miGuAuthId {
					reformatHSReplyMsg := ParseEndStrAndReformat(&HSReplyMsg)
					msg, _ := json.Marshal(reformatHSReplyMsg)
					write_err := c.Socket.WriteMessage(websocket.TextMessage, msg)
					if write_err != nil {
						log.Println("返回意识流给客户端时出错! ")
						WorldDestroyWs(c)
						return
					}

				} else {
					msg, _ := json.Marshal(HSReplyMsg)
					write_err := c.Socket.WriteMessage(websocket.TextMessage, msg)
					if write_err != nil {
						log.Println("返回意识流给客户端时出错! ")
						WorldDestroyWs(c)
						return
					}

				}

				/*
				   mongoDB保存数字人发送给前端用户的聊天记录
				*/
				//最后一次聊天的数字人
				//c.LastMsg = ISLIU
				//LastDpId := c.DpConversations.DpIds[c.LastIndex]
				senderType2 := "world"
				maxTimeStamp, chatDB_err2 := datasource.SaveWorldChatRecordMongoDB(conversation_Id, c.WorldConversations.WorldId, c.WorldConversations.WorldName, ISLIU, Wobj, senderType2)
				// 错误处理
				if chatDB_err2 != nil {
					log.Println(config.ColorRed, "保存数字人聊天记录至数据库出错!", config.ColorReset)

					errorMsg := ErrorMessage{
						Code:    -1,
						Message: "保存数字人聊天记录至数据库出错！",
					}
					errmsg, _ := json.Marshal(errorMsg)
					_ = c.Socket.WriteMessage(websocket.TextMessage, errmsg)

					return
				}

				if c.AuthId == miGuAuthId {

					if endStr, ok := echoResponse.WObj["EndStr"]; ok {
						if endStr != "" {
							fmt.Println(" endStr ====> :", endStr)

							score, err := ExtractRating(*echoResponse)
							if err != nil {
								fmt.Println("错误提取评分: ", err)
								return
							}
							fmt.Println("推演到结局，保存结局内容...")
							// 创建 OutcomeContent 对象
							outcome := OutcomeContent{
								WObj:  echoResponse.WObj,
								ISLIU: echoResponse.ISLIU,
							}

							// 将 OutcomeContent 对象转换成 JSON 字符串
							outcomeContentBytes, err := json.Marshal(outcome)
							if err != nil {
								fmt.Println("无法将推演结局内容序列化:", err)
								return
							}

							outcomeContentStr := string(outcomeContentBytes)

							// 创建 WorldDeductionResult 对象
							deductionResult := models.WorldDeductionResult{
								WorldId:        c.WorldConversations.WorldId,
								UserId:         c.WorldConversations.Uid,
								WorldName:      c.WorldName,
								OutcomeTitle:   "推演结局", // 使用 EndStr 作为结局标题
								OutcomeContent: outcomeContentStr,
								ChatStartTime:  maxTimeStamp,
								ChatEndTime:    time.Now().Unix(),
								Score:          score,
							}

							// 保存到数据库
							_, err = models.AddWorldDeductionResult(&deductionResult)
							if err != nil {
								fmt.Println("保存推演结局内容到数据库失败:", err)
								return
							}

							fmt.Println("推演结局内容已成功保存到mysql数据库,推演结果表中。")

							chatRecordArray := datasource.WorldChatRecordArray{
								ConversationId: utils.Strval(c.WorldConversations.Uid) + "_" + utils.Strval(c.WorldConversations.WorldId),
								Timestamp:      time.Now().Unix(),
								//存个空的聊天记录数组
								Records: []datasource.WorldChatRecord{},
							}
							err = datasource.SaveWorldChatRecord(chatRecordArray)
							if err != nil {
								log.Println("MongoDB数据库，新插入一条数据出错，err: ", err)
								//ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "重置世界记忆文件,插入数据失败!"})
								return
							}
							fmt.Println(config.ColorBlue, "用户聊天到结局，MongoDB创建新的聊天数组", config.ColorReset)

						}
					}

				}

				/*
				  发送消息成功，resCode为1
				*/

				if resCode == 1 {
					/*		//增加数字人的交互量

							err := models.IncrementDigitalPersonInteractionCount(c.DpConversations.DpIds[c.LastIndex])
							if err != nil {
								log.Println(config.ColorRed, "更新交互量失败:", err, config.ColorReset)
								return
							}
							fmt.Println(config.ColorGreen, "交互量更新成功!", config.ColorReset)
					*/
					if c.AuthId != "" {
						sp, err := models.GetServiceProviderById(c.AuthId)
						if err != nil {
							fmt.Println("根据服务商id查询出错:", err)
							return
						}
						if sp != nil && c.UserSource == sp.Name {
							/* 添加服务商调用AI会话，灵感消耗日志信息 */
							museNum := int64(echoResponse.MuseValue)
							// 构建一个InspirationUsageLog实例

							/* 更新服务商的灵感值 */
							if museNum > sp.InspirationValue {
								// 处理错误或返回
								fmt.Println("服务商灵感值不足本次扣除")
								return
							}
							sp.InspirationValue = sp.InspirationValue - museNum
							sp.TotalInspiration = sp.TotalInspiration + museNum
							err := models.UpdateServiceProvider(sp)
							if err != nil {
								log.Println(config.ColorRed, "更新服务商灵感消耗值失败:", err, config.ColorReset)
								return
							} else {
								log.Println(config.ColorBlue, "更新服务商灵感消耗值成功,剩余灵感值:", sp.InspirationValue, config.ColorReset)
							}
						}

					}

				}
			}

			/*
			   type为1,表示用户无回应，数字人进行主动发送信息，进行主动关怀！！
			*/

			if sendMsg.Type == 1 {
				//响应给客户端
				HSReplyMsg := WorldSoulReplyMsg{
					Code:      resCode,
					WObj:      Wobj,
					ISLIU:     ISLIU,
					WorldName: c.WorldName,
					IsLIUId:   &c.WorldConversations.IsLiuId,
				}

				var msg []byte
				//判断是不是咪咕服务商
				if c.AuthId == miGuAuthId {
					reformatHSReplyMsg := ParseEndStrAndReformat(&HSReplyMsg)
					msg, _ = json.Marshal(reformatHSReplyMsg)

				} else {
					msg, _ = json.Marshal(HSReplyMsg)
				}
				//解析AI接口返回的数据
				//msg, _ := json.Marshal(HSReplyMsg)
				//c.LastMsg = ISLIU

				/*
				   mongoDB保存数字人发送给前端用户的聊天记录
				*/

				senderType := "world"
				maxTimeStamp, chatDB_err := datasource.SaveWorldChatRecordMongoDB(conversation_Id, c.WorldConversations.WorldId, c.WorldConversations.WorldName, ISLIU, Wobj, senderType)
				// 错误处理
				if chatDB_err != nil {
					log.Println(config.ColorRed, "保存数字人聊天记录至数据库出错!", config.ColorReset)
					errorMsg := ErrorMessage{
						Code:    -1,
						Message: "保存数字人聊天记录至数据库出错！",
					}
					errmsg, _ := json.Marshal(errorMsg)
					_ = c.Socket.WriteMessage(websocket.TextMessage, errmsg)
					return
				}

				// 回复数据至前端用户
				write_err := c.Socket.WriteMessage(websocket.TextMessage, msg)
				if write_err != nil {
					log.Println(config.ColorRed, "数字人主动关怀，返回意识流给客户端时出错!", config.ColorReset)
					WorldDestroyWs(c)
					return
				}

				if endStr, ok := echoResponse.WObj["EndStr"]; ok {
					if endStr != "" {

						fmt.Println("推演到结局，保存结局内容...")
						// 创建 OutcomeContent 对象
						outcome := OutcomeContent{
							WObj:  echoResponse.WObj,
							ISLIU: echoResponse.ISLIU,
						}

						// 将 OutcomeContent 对象转换成 JSON 字符串
						outcomeContentBytes, err := json.Marshal(outcome)
						if err != nil {
							fmt.Println("无法将推演结局内容序列化:", err)
							return
						}

						outcomeContentStr := string(outcomeContentBytes)

						// 创建 WorldDeductionResult 对象
						deductionResult := models.WorldDeductionResult{
							WorldId:        c.WorldConversations.WorldId,
							UserId:         c.WorldConversations.Uid,
							WorldName:      c.WorldName,
							OutcomeTitle:   "推演结局", // 使用 EndStr 作为结局标题
							OutcomeContent: outcomeContentStr,
							ChatStartTime:  maxTimeStamp,
							ChatEndTime:    time.Now().Unix(),
						}

						// 保存到数据库
						_, err = models.AddWorldDeductionResult(&deductionResult)
						if err != nil {
							fmt.Println("保存推演结局内容到数据库失败:", err)
							return
						}

						fmt.Println("推演结局内容已成功保存到mysql数据库,推演结果表中。")

						chatRecordArray := datasource.WorldChatRecordArray{
							ConversationId: utils.Strval(c.WorldConversations.Uid) + "_" + utils.Strval(c.WorldConversations.WorldId),
							Timestamp:      time.Now().Unix(),
							//存个空的聊天记录数组
							Records: []datasource.WorldChatRecord{},
						}
						err = datasource.SaveWorldChatRecord(chatRecordArray)
						if err != nil {
							log.Println("MongoDB数据库，新插入一条数据出错，err: ", err)
							//ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "重置世界记忆文件,插入数据失败!"})
							return
						}
						fmt.Println(config.ColorBlue, "用户聊天到结局，MongoDB创建新的聊天数组", config.ColorReset)

					}
				}

				/*
				  发送消息成功，resCode为1
				*/
				if resCode == 1 {
					/*//增加数字人的交互量
					err := models.IncrementDigitalPersonInteractionCount(c.DpConversations.DpIds[c.LastIndex])
					if err != nil {
						log.Println(config.ColorRed, "更新交互量失败:", err, config.ColorReset)
					}
					fmt.Println(config.ColorGreen, "交互量更新成功!", config.ColorReset)*/
					if c.AuthId != "" {
						sp, err := models.GetServiceProviderById(c.AuthId)
						if err != nil {
							fmt.Println("根据服务商id查询出错:", err)
							return
						}
						if sp != nil && c.UserSource == sp.Name {
							/* 添加服务商调用AI会话，灵感消耗日志信息 */
							museNum := int64(echoResponse.MuseValue)

							/* 更新服务商的灵感值 */
							if museNum > sp.InspirationValue {
								// 处理错误或返回
								fmt.Println("服务商灵感值不足本次扣除")
								return
							}
							sp.InspirationValue = sp.InspirationValue - museNum
							sp.TotalInspiration = sp.TotalInspiration + museNum
							err := models.UpdateServiceProvider(sp)
							if err != nil {
								log.Println(config.ColorRed, "更新服务商灵感消耗值失败:", err, config.ColorReset)
								return
							} else {
								log.Println(config.ColorBlue, "更新服务商灵感消耗值成功,剩余灵感值:", sp.InspirationValue, config.ColorReset)
							}
						}

					}
				}
			}
		}()

	}

}

// ExtractRating 从响应中提取整体评分

func ExtractRating(response WorldEchoResponse) (int, error) {
	endStr, ok := response.WObj["EndStr"].(string)
	if !ok || endStr == "" {
		return 0, nil
	}

	lines := strings.Split(endStr, "\n")
	for _, line := range lines {
		if strings.Contains(line, "【整体评分】") {
			scoreStr := strings.TrimSpace(strings.Split(line, "：")[1])
			score, err := strconv.Atoi(scoreStr)
			if err != nil {
				return 0, fmt.Errorf("评分转换错误: %v", err)
			}
			return score, nil
		}
	}

	return 0, fmt.Errorf("未找到评分信息")
}
func ExtractRating1(response WorldEchoResponse) string {

	endStr, ok := response.WObj["EndStr"].(string)
	if !ok {
		return "评分信息不可用"
	}

	lines := strings.Split(endStr, "\n")
	for _, line := range lines {
		if strings.Contains(line, "【整体评分】") {
			// 假设评分总是单个数字跟在冒号和换行符后面
			return strings.TrimSpace(strings.Split(line, "：")[1])
		}
	}

	return "评分信息不可用"
}

/* ============================================================================================= */

// ParseEndStrAndReformat 重新解析 WorldSoulReplyMsg 中的 WObj 并返回一个新的结构体
func ParseEndStrAndReformat(response *WorldSoulReplyMsg) *WorldSoulReplyMsg {
	if response == nil || response.WObj == nil {
		return nil // 如果输入是nil，直接返回nil
	}

	//newResponse := *response // 创建一个新的响应体对象副本

	newResponse := *DeepCopy(response)
	if len(newResponse.WObj) == 0 && strings.Contains(newResponse.ISLIU, "【任务提示】") {
		newResponse.MessageStatusType = "prologue"
	} else if endStr, ok := newResponse.WObj["EndStr"].(string); ok && endStr != "" {
		newResponse.MessageStatusType = "end"
	} else {
		newResponse.MessageStatusType = "chatting"
	}

	endStr, ok := newResponse.WObj["EndStr"].(string)
	if ok {
		if endStr != "" {
			// 解析 "EndStr" 中的详细字段
			title := strings.Split(endStr, "@")[0]                                // 提取 '@' 前的标题
			overallScore := extractBetween(endStr, "【整体评分】：", "\n")               // 提取整体评分
			objectiveEvaluation := extractBetween(endStr, "【客观评价】：", "## 【整体评分】") // 提取客观评价至字符串末尾

			// 将 "EndStr" 结构化为 JSON 对象
			endStrObj := map[string]interface{}{
				"title":               title,
				"overallScore":        strings.TrimSpace(overallScore),
				"objectiveEvaluation": strings.TrimSpace(objectiveEvaluation),
			}

			newResponse.WObj["EndStr"] = endStrObj // 将格式化后的结论字符串对象重新赋值给响应
		} else {
			newResponse.WObj["EndStr"] = nil
		}

	}

	// 无论 "EndStr" 是否存在，均检查和处理 '地点' 和 '表情'
	if address, exists := newResponse.WObj["地点"]; exists {
		newResponse.WObj["address"] = address
		delete(newResponse.WObj, "地点")
	}
	if emotion, exists := newResponse.WObj["表情"]; exists {
		newResponse.WObj["emotion"] = emotion
		delete(newResponse.WObj, "表情")
	}
	if chatTime, exists := newResponse.WObj["时间"]; exists {
		newResponse.WObj["time"] = chatTime
		delete(newResponse.WObj, "时间")
	}
	return &newResponse // 返回修改后的新响应体
}

// extractBetween 查找并提取开始和结束分隔符之间的子字符串
func extractBetween(s, start, end string) string {
	startIdx := strings.Index(s, start)
	if startIdx == -1 {
		return ""
	}
	startPos := startIdx + len(start)
	endIdx := strings.Index(s[startPos:], end)
	if endIdx == -1 {
		return s[startPos:]
	}
	return s[startPos : startPos+endIdx]
}

// extractToEnd 查找并提取从指定开始分隔符到字符串末尾的内容
func extractToEnd(s, start string) string {
	startIdx := strings.Index(s, start)
	if startIdx == -1 {
		return ""
	}
	return s[startIdx+len(start):]
}

//深拷贝对象
func DeepCopy(msg *WorldSoulReplyMsg) *WorldSoulReplyMsg {
	// 创建一个新的 WorldSoulReplyMsg 实例
	newMsg := &WorldSoulReplyMsg{
		Code:      msg.Code,
		ISLIU:     msg.ISLIU,
		WorldName: msg.WorldName,
	}

	// 深拷贝 WObj map
	if msg.WObj != nil {
		newMsg.WObj = make(map[string]interface{})
		for k, v := range msg.WObj {
			newMsg.WObj[k] = v // 注意这里只是简单拷贝，对于更复杂的对象可能需要更深层次的拷贝
		}
	}

	// 复制可选指针类型字段 IsLIUId
	if msg.IsLIUId != nil {
		newIsLIUId := *msg.IsLIUId // 创建 IsLIUId 的副本
		newMsg.IsLIUId = &newIsLIUId
	}

	// 复制其他可选字段
	if msg.MessageStatusType != "" {
		newMsg.MessageStatusType = msg.MessageStatusType
	}

	return newMsg
}

func (c *WorldClient) WorldWrite() {
	defer func() {
		_ = c.Socket.Close()
	}()
	for {
		select {

		case message, ok := <-c.Send:
			if !ok {
				_ = c.Socket.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}
			/*
				resCode := message.Code
				status := message.Status
				ISLIU := message.ISLIU
			*/

			log.Println(c.WorldConversations.Uid, "接受消息:", message)
			replyMsg := WorldReplyMsg{
				Code:    e.WebsocketSuccess,
				Content: fmt.Sprintf("%s", message),
			}
			msg, _ := json.Marshal(replyMsg)
			_ = c.Socket.WriteMessage(websocket.TextMessage, msg)
		}
	}
}

/* ============================================================================================= */

// ParseEndStrAndReformat 重新结构化 WorldEchoRespones，以包含结论消息的详细拆分
func ParseEndStrAndReformat1(response *WorldEchoResponse) {
	if response == nil || response.WObj == nil {
		return
	}

	endStr, ok := response.WObj["EndStr"].(string)
	if !ok || endStr == "" {
		return
	}

	// 解析 "EndStr" 中的详细字段
	title := strings.Split(endStr, "@")[0]                               // 提取 '@' 前的标题
	overallScore := extractBetween(endStr, "【整体评分】：", "\n")              // 提取整体评分
	objectiveEvaluation := extractBetween(endStr, "【客观评价】：", "**言行举止**") // 提取客观评价

	// 将 "EndStr" 结构化为 JSON 对象
	endStrObj := map[string]interface{}{
		"title":               title,
		"OverallScore":        strings.TrimSpace(overallScore),
		"ObjectiveEvaluation": strings.TrimSpace(objectiveEvaluation),
	}

	response.WObj["EndStr"] = endStrObj // 将格式化后的结论字符串对象重新赋值给响应

	// 可选处理其他字段如 '地点' 和 '表情'
	if address, exists := response.WObj["地点"]; exists {
		response.WObj["address"] = address
		delete(response.WObj, "地点")
	}
	if emotion, exists := response.WObj["表情"]; exists {
		response.WObj["emotion"] = emotion
		delete(response.WObj, "表情")
	}
}

// ParseEndStrAndReformat 将 WorldSoulReplyMsg 中的 WObj 修改后返回一个新的 WorldSoulReplyMsg 结构体
func ParseEndStrAndReformat2(response *WorldSoulReplyMsg) *WorldSoulReplyMsg {
	if response == nil || response.WObj == nil {
		return nil // 如果输入是nil，直接返回nil
	}

	newResponse := *response // 创建一个新的响应副本以避免修改原始数据

	endStr, ok := newResponse.WObj["EndStr"].(string)
	if !ok || endStr == "" {
		return &newResponse // 如果没有 EndStr 或者为空，返回原始数据的副本
	}

	// 解析 "EndStr" 中的详细字段
	title := strings.Split(endStr, "@")[0]                  // 提取 '@' 前的标题
	overallScore := extractBetween(endStr, "【整体评分】：", "\n") // 提取整体评分
	objectiveEvaluation := extractToEnd(endStr, "【客观评价】：")  // 提取客观评价

	// 将 "EndStr" 结构化为 JSON 对象
	endStrObj := map[string]interface{}{
		"title":               title,
		"OverallScore":        strings.TrimSpace(overallScore),
		"ObjectiveEvaluation": strings.TrimSpace(objectiveEvaluation),
	}

	newResponse.WObj["EndStr"] = endStrObj // 将格式化后的结论字符串对象重新赋值给响应

	// 可选处理其他字段如 '地点' 和 '表情'
	if address, exists := newResponse.WObj["地点"]; exists {
		newResponse.WObj["address"] = address
		delete(newResponse.WObj, "地点")
	}
	if emotion, exists := newResponse.WObj["表情"]; exists {
		newResponse.WObj["emotion"] = emotion
		delete(newResponse.WObj, "表情")
	}

	return &newResponse // 返回修改后的新响应体
}

func ParseEndStrAndReformat3(response *WorldSoulReplyMsg) *WorldSoulReplyMsg {
	if response == nil || response.WObj == nil {
		return nil // If the input is nil, return nil
	}

	newResponse := *response // Create a copy of the response to modify

	// Determine the message type based on the presence of specific keywords or structures
	if len(newResponse.WObj) == 0 && strings.Contains(newResponse.ISLIU, "【任务提示】") {
		newResponse.MessageStatusType = "开场白"
	} else if endStr, ok := newResponse.WObj["EndStr"].(string); ok && endStr != "" {
		newResponse.MessageStatusType = "结局"
	} else {
		newResponse.MessageStatusType = "会话中消息"
	}

	// Further reformatting based on the presence of "EndStr"
	if endStr, ok := newResponse.WObj["EndStr"].(string); ok {
		if endStr != "" {
			// Parse details from "EndStr"
			title := strings.Split(endStr, "@")[0]
			overallScore := extractBetween(endStr, "【整体评分】：", "\n")
			objectiveEvaluation := extractToEnd(endStr, "【客观评价】：")

			// Structurize "EndStr" into a JSON object
			endStrObj := map[string]interface{}{
				"title":               title,
				"overallScore":        strings.TrimSpace(overallScore),
				"objectiveEvaluation": strings.TrimSpace(objectiveEvaluation),
			}

			newResponse.WObj["EndStr"] = endStrObj // Assign the reformatted conclusion string object back to the response
		}
	}

	// Handle additional fields such as '地点' and '表情'
	if address, exists := newResponse.WObj["地点"]; exists {
		newResponse.WObj["address"] = address
		delete(newResponse.WObj, "地点")
	}
	if emotion, exists := newResponse.WObj["表情"]; exists {
		newResponse.WObj["emotion"] = emotion
		delete(newResponse.WObj, "表情")
	}

	return &newResponse // Return the modified response
}

// 使用例
func ExampleSend() {
	IsLiu_Id := "d018fd63c598f4a13e31f7f8faf0ac15"
	originalMsg := WorldSoulReplyMsg{
		Code: 1,
		WObj: map[string]interface{}{"EndStr": "确定下单@\n## 【整体评分】： 90\n\n## 【客观评价】：\n\n这位业务经理在与客户沟通的过程中展现出了良好的专业素养和沟通技巧。他能清晰地介绍产品，并针对客户提出的问题和疑虑进行耐心解答，并根据客户的需求进行灵活调整，最终促成了交易。\n\n**言行举止**:  业务经理在与客户沟通的过程中保持着礼貌和专业的态度，没有出现任何不当言行。\n\n**优势**:  业务经理对产品知识掌握熟练，能够根据客户的需求进行灵活的方案调整，并展现出一定的谈判技巧，最终促成了交易。\n\n**不足与建议**: 在价格方面，业务经理可以尝试更早地了解客户的心理价位，以便制定更有针对性的报价策略。此外，在介绍产品时，可以更加突出云电脑相比传统电脑的优势，例如节省维护成本、方便升级等。 \n",
			"地点": "老板办公室",
			"表情": "满意"},
		ISLIU:     "Some text",
		WorldName: "Example World",
		IsLIUId:   &IsLiu_Id,
	}

	// 转换消息
	transformedMsg := ParseEndStrAndReformat(&originalMsg)

	// 序列化消息为JSON
	jsonMsg, err := json.Marshal(transformedMsg)
	if err != nil {
		log.Printf("JSON编码失败: %v", err)
		return
	}

	// 发送消息
	//err = c.Socket.WriteMessage(websocket.TextMessage, jsonMsg)
	//if err != nil {
	//	log.Println("发送WebSocket消息失败: ", err)
	//	WorldDestroyWs(c) // 关闭WebSocket连接
	//}

	fmt.Println("jsonMsg ==> ", string(jsonMsg))
}
