package service

import (
	"WorldEpcho/src/config"
	"WorldEpcho/src/config/e"
	"WorldEpcho/src/datasource"
	"WorldEpcho/src/models"
	"WorldEpcho/src/utils"
	"github.com/gin-contrib/sessions"
	"os"
	"strconv"
	"strings"
	"time"

	//"time"

	//"chat/cache"
	//"chat/conf"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	//"strconv"
	//"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"` // 5  ==>
	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
	ErrorMessage      string                 `json:"ErrorMessage,omitempty"`      //可选字段
}

/*
构建Client表
*/
type WorldClient struct {
	//DpConversations *models.DpConversations
	WorldConversations *models.WorldConversation
	Socket             *websocket.Conn
	//Send               chan *WorldEchoResponse
	Send       chan *WorldSoulReplyMsg
	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"`
}

/*
 type WorldEchoResponseAndErrorMsg struct {
	SoulReplyMsg WorldSoulReplyMsg //WorldSoulReplyMsg
	ErrorMessage WorldErrorMessage `json:"ErrorMessage,omitempty"`
 }
*/

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

//世界websocket控制器
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,

			Send:   make(chan *WorldSoulReplyMsg, 1024), // 创建一个有缓冲的管道
			AuthId: ServiceProviderId,
		}

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

		go newClient.WorldWrite() // 为每个客户端启动写消息协程

		// 用户会话注册到用户管理上
		//WorldManager.Register <- newClient
		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

			}
			/* 创建响应体 WorldEchoRespones */
			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,
			}

			//向管道写入开场白消息
			newClient.Send <- &HSReplyMsg

			/*
				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 := WorldSoulReplyMsg{
					Code:         -1,
					ErrorMessage: "保存数字人聊天记录至数据库出错！",
				}
				/*		errorMsg := WorldErrorMessage{
							Code:    -1,
							Message: "保存数字人聊天记录至数据库出错！",
						}
						errmsg, _ := json.Marshal(errorMsg)
						_ = newClient.Socket.WriteMessage(websocket.TextMessage, errmsg)*/
				newClient.Send <- &errorMsg
				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)

					}
				}
			*/
			errorMsg := WorldSoulReplyMsg{
				Code:         -1,
				ErrorMessage: "客户端发送的数据格式不正确！",
			}

			c.Send <- &errorMsg

			//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)
					}
				}*/
				errorMsg := WorldSoulReplyMsg{
					Code:         -1,
					ErrorMessage: "请求AI模型会话失败！",
				}

				c.Send <- &errorMsg

				// 删除会话记录
				/*		if chat_err.Error() == "调用会话接口失败无法获取意识流" {
							dropConversationErr := models.DeleteConversation()
							if dropConversationErr != nil {
								log.Println("删除会话失败")

							}

						}
				*/
				return
			} /*else {
				c.Send <- echoResponse // 将回应消息放入 `Send` 频道
			}*/

			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: 会话意识流为空... ")

				errorMsg := WorldSoulReplyMsg{
					Code:         -1,
					ErrorMessage: "AI模型会话意识流为空.",
				}

				c.Send <- &errorMsg

				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)
					*/
					errorMsg := WorldSoulReplyMsg{
						Code:         -1,
						ErrorMessage: "保存用户聊天记录至数据库出错!",
					}

					c.Send <- &errorMsg
					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
						}*/
					// 将处理后的消息发送到Write协程
					c.Send <- reformatHSReplyMsg

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

					c.Send <- &HSReplyMsg
				}

				/*
				   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)
					*/
					errorMsg := WorldSoulReplyMsg{
						Code:         -1,
						ErrorMessage: "保存数字人聊天记录至数据库出错!",
					}

					c.Send <- &errorMsg
					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)
					// 将处理后的消息发送到Write协程
					c.Send <- reformatHSReplyMsg
				} else {
					//msg, _ = json.Marshal(HSReplyMsg)
					c.Send <- &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)*/
					errorMsg := WorldSoulReplyMsg{
						Code:         -1,
						ErrorMessage: "保存数字人聊天记录至数据库出错!",
					}

					c.Send <- &errorMsg
					return
				}

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

/*
 实现WorldWrite方法
  WorldWrite方法需要修改以适应从通道中读取*WorldEchoRespones类型的数据并将其发送到WebSocket
*/
func (c *WorldClient) WorldWrite() {
	defer func() {
		_ = c.Socket.Close()
	}()
	for {
		select {
		case message, ok := <-c.Send:
			if !ok {
				// 如果通道被关闭，发送WebSocket关闭消息并退出goroutine
				_ = c.Socket.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}
			// 序列化消息为JSON
			msg, err := json.Marshal(message)
			if err != nil {
				log.Printf("Error marshaling message: %s\n", err)
				continue
			}
			// 发送序列化后的消息到WebSocket连接
			if err := c.Socket.WriteMessage(websocket.TextMessage, msg); err != nil {
				// 处理写入错误，例如可以记录日志或关闭连接
				log.Printf("WebSocket write error: %s\n", err)
				return
			}
		}
	}
}

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

func (c *WorldClient) WorldWrite1() {
	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)
		}
	}
}
