package service

import (
	"WorldEpcho/src/config"
	"WorldEpcho/src/config/e"
	"WorldEpcho/src/datasource"
	"WorldEpcho/src/models"
	"WorldEpcho/src/utils"
	"errors"
	"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 DpsSendMsg struct {
	Type    int    `json:"type"`
	Content string `json:"content"`
}

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

// 转发AI接口意识流响应给前端
type DpsHuaSoulReplyMsg struct {
	Code         int                    `json:"code"`
	Status       map[string]interface{} `json:"status"`
	ISLIU        string                 `json:"ISLIU"`
	ResponseName string                 `json:"responseName"`
	ResponseDpId int64                  `json:"responseDpId"`
}

/*
构建Client表
*/
type Clients struct {
	AppId           int64
	UUID            string
	DpConversations *models.DpConversations
	Socket          *websocket.Conn
	Send            chan *HuaSoulEchoRespones
	DpNames         []string
	LastIndex       int
	//LastSender      string //这里保存的意识流id
	//LastDpId        int64
	LastMsg string
}

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

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

// 用户管理
type DpsClientManager struct {
	Clients map[string]*Clients
	//Broadcast  chan *Broadcast
	Reply      chan *Clients
	Register   chan *Clients
	Unregister chan *Clients
}

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

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

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

func DpsWsHandler(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("UserID")
	if userId == nil {
		// 处理session中未找到值的情况，返回错误信息
		/*这里是双保险为了测试用*/
		userId = ctx.Query("id")
		if userId == nil {
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "Session中未找到用户ID,用户未登录"})
			fmt.Println(config.ColorYellow, "Session中未找到用户ID,用户未登录", config.ColorReset)
			return
		}
	}
	fmt.Println("chat session UserID：", userId)
	appId := ctx.Query("app_id")
	var app_id int64
	if appId != "" {
		app_id, err = strconv.ParseInt(appId, 10, 64)
		if err != nil {
			//app_id = 2
			fmt.Println("app_id:", app_id)
		}
	}

	user_Id, ok := userId.(string)
	if !ok {
		// 类型断言失败，处理类型不匹配的情况
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户ID类型错误"})
		return
	}
	//userId作为string类型的值进行后续操作
	_, b := config.WorldLoginCacheCode.Get(user_Id)

	uid, err := strconv.Atoi(user_Id)
	if err != nil {
		fmt.Println("用户id转换失败:", err)
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户id转换失败"})
		return
	}

	//从session中获取用户id
	/*
	   判断用户是否登录
	*/
	//定义会话主题
	var ConversationTitle string
	var DpNames []string
	var IsLiuIds []string
	if b {
		DpIds := ctx.Query("DpIds")
		UUID := ctx.Query("uuid")
		DpIdArr := []int64{}
		digitalPersonArr := []*models.DigitalPerson{}
		DpIdStrArr := []string{}
		// 分割字符串，得到单独的数值字符串
		DpIdsSplit := strings.Split(DpIds, ",")
		for _, DpIdStr := range DpIdsSplit {
			// 数字人id字符串数组
			DpIdStrArr = append(DpIdStrArr, DpIdStr)
			// 将字符串转换为 int64 类型
			dpId, err := strconv.ParseInt(DpIdStr, 10, 64)
			if err != nil {
				ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "数字人id类型转换出错"})
				//continue
				return
			}
			// 将转换后的数值添加到数组
			DpIdArr = append(DpIdArr, dpId)
			//查询数据库，根据数字人Id查询数字人信息
			digitalPerson, err := models.GetDigitalPersonByID(dpId)
			if err != nil {
				ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户与数字人创建会话时，查询数字人失败"})
				log.Println(err.Error())
				return
			}
			//fmt.Println("digitalPerson: ", digitalPerson)
			DpNames = append(DpNames, digitalPerson.Name)
			digitalPersonArr = append(digitalPersonArr, digitalPerson)

		}
		//拼接会话主题
		ConversationTitle = "用户Id为" + user_Id + "的用户和数字人" + strings.Join(DpNames, "和") + "开始会话"
		fmt.Println("ConversationTitle: ", ConversationTitle)

		// 根据用户id和数字人id，查询会话表中是否有会话记录
		var conversation *models.DpConversations

		//如果前端没有传AppId
		app_id = 0
		conversation, err := models.QueryConversationsByUserIdAndDpId(int64(uid), DpIdArr, app_id)
		if err != nil {
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "查询会话记录失败！"})
			return
		}

		var (
			//conversation models.Conversation
			ISULU_ID string
		)

		if conversation == nil {
			// 如果查询不到记录，则插入一条新的会话记录
			//创建调用AI接口实例
			/*
				    var param []string // 定义一个初始为空的切片
					param = append(param, digital_Id)
			*/

			if UUID != "" {
				fmt.Println(config.ColorCyan, "UUID: ", UUID, config.ColorReset)
				//

				/*
					val_uuid := AppCache[UUID].UUID_Val
					fmt.Println(config.ColorYellow, "缓存中的UUID: ", val_uuid, config.ColorReset)
				*/
				for i := 0; i < len(DpIdArr); i++ {
					apiCode, ISULU_ID, err := HuaSoulNewAPI(utils.Strval(DpIdArr[i]), UUID)
					if err != nil {
						ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "数字人会话创建连接，失败！"})
					}
					if apiCode != 1 && ISULU_ID == "" {
						ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "创建调用数字人会话接口实例，失败！"})

					} else {

						IsLiuIds = append(IsLiuIds, ISULU_ID)
					}

				}

				conversation = &models.DpConversations{
					Uid:      int64(uid),
					DpIds:    DpIdArr,
					Title:    ConversationTitle,
					IsliuIds: IsLiuIds,
				}
				if appId == "" {
					conversation.AppId = 0
				} else {
					conversation.AppId = app_id
				}
				/*
				 往mysql数据库的会话表中插入一条记录
				*/
				err = models.CreateDpConversations(conversation)
				if err != nil {
					ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "创建会话后，向数据库插入数据失败！"})
					return
				}

			} else {
				//如果前端没有传uuid，参数个数为1
				for i := 0; i < len(DpIdArr); i++ {
					apiCode, ISULU_ID, err := HuaSoulNewAPI(utils.Strval(DpIdArr[i]))
					if err != nil {
						ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "数字人会话创建连接，失败！"})
					}
					if apiCode != 1 && ISULU_ID == "" {
						ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "创建调用数字人会话接口实例，失败！"})

					} else {

						IsLiuIds = append(IsLiuIds, ISULU_ID)
					}

				}

				conversation = &models.DpConversations{
					Uid:      int64(uid),
					DpIds:    DpIdArr,
					Title:    ConversationTitle,
					IsliuIds: IsLiuIds,
				}
				if appId == "" {
					conversation.AppId = 0
				} else {
					conversation.AppId = app_id
				}
				/*
				 往mysql数据库的会话表中插入一条记录
				*/
				err = models.CreateDpConversations(conversation)
				if err != nil {
					ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "创建会话后，向数据库插入数据失败！"})
					return
				}

			}

		} else {
			for i := 0; i < len(conversation.IsliuIds); i++ {
				ISULU_ID = conversation.IsliuIds[i]
				// 如果查询到记录，调用查询意识流Id接口判断意识流id是否有效，若无效则修改意识流ID为新的意识流ID
				flag := HuaSoulFindISLIUID(ISULU_ID)
				fmt.Println("查询意识流Id, flag: ", flag)
				//没找到
				if !flag {
					//创建调用AI接口实例
					if UUID != "" {
						fmt.Println(config.ColorCyan, "UUID为: ", UUID, config.ColorReset)
						/*
							apiCode, ISULU_ID, err := HuaSoulNewAPI(digital_Id, UUID)
							if err != nil {
								ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "数字人会话创建连接，失败！"})
							}
							if apiCode != 1 && ISULU_ID == "" {
								ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "创建调用数字人会话接口实例，失败！"})
							}
						*/
						for i := 0; i < len(DpIdArr); i++ {
							apiCode, ISULU_ID, err := HuaSoulNewAPI(utils.Strval(DpIdArr[i]), UUID)
							if err != nil {
								ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "数字人会话创建连接，失败！"})
							}
							if apiCode != 1 && ISULU_ID == "" {
								ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "创建调用数字人会话接口实例，失败！"})

							} else {

								IsLiuIds = append(IsLiuIds, ISULU_ID)
							}

						}

						// 把调用AI接口获取的新意识流ID赋给conversation.IsliuId
						conversation.IsliuIds = IsLiuIds
						if appId == "" {
							conversation.AppId = 0
						} else {
							conversation.AppId = app_id
						}

						//更新数据库中会话表对应会话的意识流id
						err = models.UpdateDpConversations(conversation)
						if err != nil {
							ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "更新会话意识流id失败！"})
							return
						}

					} else {

						//UUID为空时候，只传一个参数即可
						for i := 0; i < len(DpIdArr); i++ {
							apiCode, ISULU_ID, err := HuaSoulNewAPI(utils.Strval(DpIdArr[i]))
							if err != nil {
								ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "数字人会话创建连接，失败！"})
							}
							if apiCode != 1 && ISULU_ID == "" {
								ctx.JSON(http.StatusOK, gin.H{"code": 0, "content": "创建调用数字人会话接口实例，失败！"})

							} else {

								IsLiuIds = append(IsLiuIds, ISULU_ID)
							}

						}

						// 把调用AI接口获取的意识流ID赋给conversation.IsliuId
						conversation.IsliuIds = IsLiuIds
						if appId == "" {
							conversation.AppId = 0
						} else {
							conversation.AppId = app_id
						}
						//更新数据库中会话表对应会话的意识流id
						err = models.UpdateDpConversations(conversation)
						if err != nil {
							ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "更新会话意识流id失败！"})
							return
						}

					}

				}
			}

		}

		// 创建一个用户客户端会话实例
		newClient := &Clients{
			AppId:           app_id,
			UUID:            UUID,
			DpConversations: conversation,
			Socket:          conn,
			Send:            nil,
			DpNames:         DpNames,
			//LastSender:      "",
			//LastDpId:        0,
			LastIndex: -1,
			LastMsg:   "",
		}
		// 用户会话注册到用户管理上
		DpsManager.Register <- newClient

		// ---------------------------------------- //

		url := config.Conf.SoulUrl + "/soul/neural"
		for i := 0; i < len(IsLiuIds); i++ {
			fileName := "./neural/" + IsLiuIds[i] + ".CFN"
			// 获取文件信息
			_, err = os.Stat(fileName)
			if err == nil {
				fmt.Println("文件存在")
				// 构造请求参数
				request := SoulNeuralRequest{
					Auth:    config.Conf.SoulAuth,
					Type:    1, // 1表示上载
					ISLIUid: IsLiuIds[i],
				}
				// 调用函数
				_, 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.DpsRead()
		//go newClient.Write()

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

}

func DpsDestroyWs(c *Clients) { // 避免忘记关闭，所以要加上close
	/*
	   当聊天socket连接结束时，保存用户的应用数据到用户应用数据表
	*/
	strUid := utils.Strval(c.DpConversations.Uid)
	strDpId := utils.Strval(c.DpConversations.DpIds)
	if strUid == "" || strDpId == "" || c.AppId == 0 {
		fmt.Println(config.ColorRed, "用户id或者数字人id为空，或应用id为0", config.ColorReset)

	} else {
		if c.AppId == 2 {
			err := AddAppDataWSClose(c.AppId, strUid, strDpId)
			if err != nil {
				log.Println(config.ColorRed, "保存用户的应用数据到用户应用数据表出错!", config.ColorReset)
				return
			} else {
				log.Println(config.ColorGreen, "保存用户的应用数据到用户应用数据表成功!", config.ColorReset)
			}

		}
	}

	DpsManager.Unregister <- c
	_ = c.Socket.Close()
	c.Socket = nil

	//关闭websocket之前，下载关于数字人的神经网络记忆文件
	url := config.Conf.SoulUrl + "/soul/neural"
	for i := 0; i < len(c.DpConversations.IsliuIds); i++ {
		fileName := "./neural/" + c.DpConversations.IsliuIds[i] + ".CFN"

		// 构造请求参数
		request := SoulNeuralRequest{
			Auth:    config.Conf.SoulAuth,
			Type:    0, // 0表示下载
			ISLIUid: c.DpConversations.IsliuIds[i],
		}
		// 调用函数
		err1 := SoulNeuralFileDownload(url, request, fileName)
		if err1 != nil {
			log.Printf("Error during soul neural transfer: %v", err1)
		}
		//清除uuid缓存
		if c.UUID != "" {
			if _, ok := AppCache[c.UUID]; ok {
				delete(AppCache, c.UUID)
				fmt.Println(config.ColorCyan, "缓存清除成功!", c.UUID, config.ColorReset)
			}
		}
	}

}

/*
 从websocket读取客户端用户的消息，然后服务器回应前端一个消息
*/
func (c *Clients) DpsRead() {
	//延迟关闭websocket
	defer DpsDestroyWs(c)
	/*
	  死循环执行websocket消息接收和发送
	*/
	for {
		c.Socket.PongHandler()
		sendMsg := new(DpsSendMsg)
		err := c.Socket.ReadJSON(&sendMsg)
		if err != nil {
			log.Println("数据格式不正确", err)
			// 向前端返回数据格式不正确的状态码和消息
			errorMsg := DpsErrorMessage{
				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)
			//剔除注册的客户端用户
			DpsManager.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.conversation.Uid) + "_" + utils.Strval(c.conversation.DpId)
			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.DpsHuaSoulEchoAPI(sendMsg)
			if c.Socket == nil {
				return
			}
			if chat_err != nil {
				log.Println("会话失败")
				// 向前端返回数据格式不正确的状态码和消息
				errorMsg := DpsErrorMessage{
					Code:    -1,
					Message: "会话失败",
				}

				// 将错误消息对象转换为 JSON 字符串
				errmsg, errMarshal := json.Marshal(errorMsg)
				if errMarshal != nil {
					// 如果 JSON 编码失败，则打印错误
					log.Printf("DpsHuaSoulEchoAPI 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(c.DpConversations.Uid, c.DpConversations.DpIds[c.LastIndex], c.DpConversations.AppId)
					if dropConversationErr != nil {
						log.Println("删除会话失败")

					}

				}

				return
			}

			resCode := echoResponse.Code
			status := echoResponse.Status
			ISLIU := echoResponse.ISLIU

			if ISLIU == "" || status == nil {
				log.Println("会话意识流为空...")
				// 向前端返回数据格式不正确的状态码和消息
				errorMsg := DpsErrorMessage{
					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.SaveChatRecordMongoDB(conversation_Id, c.DpConversations.Uid, 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 := DpsHuaSoulReplyMsg{
					Code:   resCode,
					Status: status,
					ISLIU:  ISLIU,
					//Sender: c.DpNames[c.LastIndex],
				}
				if c.LastIndex != -1 {
					HSReplyMsg.ResponseName = c.DpNames[c.LastIndex]
					HSReplyMsg.ResponseDpId = c.DpConversations.DpIds[c.LastIndex]
					fmt.Println("ResponseName: ", c.DpNames[c.LastIndex])
					fmt.Println("ResponseDpId: ", c.DpConversations.DpIds[c.LastIndex])
				}
				msg, _ := json.Marshal(HSReplyMsg)
				write_err := c.Socket.WriteMessage(websocket.TextMessage, msg)
				if write_err != nil {
					log.Println("返回意识流给客户端时出错! ")
					DpsDestroyWs(c)
					return
				}
				/*
				   mongoDB保存数字人发送给前端用户的聊天记录
				*/
				//最后一次聊天的数字人
				//c.LastMsg = ISLIU
				LastDpId := c.DpConversations.DpIds[c.LastIndex]
				senderType2 := "bot"
				chatDB_err2 := datasource.SaveChatRecordMongoDB(conversation_Id, LastDpId, ISLIU, status, 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
				}

				/*
				  发送消息成功，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)
				}
			}

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

			if sendMsg.Type == 1 {
				//响应给客户端
				HSReplyMsg := DpsHuaSoulReplyMsg{
					Code:   resCode,
					Status: status,
					ISLIU:  ISLIU,
				}
				if c.LastIndex != -1 {
					HSReplyMsg.ResponseName = c.DpNames[c.LastIndex]
					HSReplyMsg.ResponseDpId = c.DpConversations.DpIds[c.LastIndex]
					fmt.Println("ResponseName: ", c.DpNames[c.LastIndex])
					fmt.Println("ResponseDpId: ", c.DpConversations.DpIds[c.LastIndex])
				}
				//解析AI接口返回的数据
				msg, _ := json.Marshal(HSReplyMsg)
				//c.LastMsg = ISLIU

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

				senderType := "bot"
				chatDB_err := datasource.SaveChatRecordMongoDB(conversation_Id, c.DpConversations.DpIds[c.LastIndex], ISLIU, status, 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)
					DpsDestroyWs(c)
					return
				}
				/*
				  发送消息成功，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)
				}
			}
		}()

	}

}

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

func (c *Clients) DpsWrite() {
	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.DpConversations.Uid, "接受消息:", message)
			replyMsg := ReplyMsg{
				Code:    e.WebsocketSuccess,
				Content: fmt.Sprintf("%s", message),
			}
			msg, _ := json.Marshal(replyMsg)
			_ = c.Socket.WriteMessage(websocket.TextMessage, msg)
		}
	}
}

/*
func saveChatRecordMongoDB(conversationId string, senderId int64, message string, status map[string]interface{}, senderType string) error {
	chatRecord, err := datasource.GetChatRecordByConversationID(conversationId)
	if err != nil {
		log.Println("保存聊天会话到MongoDB数据库，err: ", err)
		return err
	}
	//timeString := utils.GetNormalTimeString(time.Now())

	// 如果数据库中，聊天记录表没有这个聊天记录则插入一条
	if chatRecord == nil {
		chatRecordArray := datasource.ChatRecordArray{
			ConversationId: conversationId,
			Records: []datasource.ChatRecord{
				{SenderId: senderId, Timestamp: time.Now().Unix(), Message: message, Status: status, SenderType: senderType},
			},
		}
		err = datasource.SaveChatRecordArray(chatRecordArray)
		if err != nil {
			log.Println("MongoDB数据库插入一条数据，err: ", err)
			return err
		}
		fmt.Println("ChatRecordArray  first saved successfully")
	} else {
		// 如果数据库中已经存在聊天记录，则更新记录
		chatRecords := []datasource.ChatRecord{
			{SenderId: senderId, Timestamp: time.Now().Unix(), Message: message, Status: status, SenderType: senderType},
		}
		err := datasource.AddChatRecordToConversation(conversationId, chatRecords)
		if err != nil {
			log.Println("MongoDB数据库更新一条数据，err: ", err)
			return err
		}
		fmt.Println("ChatRecordArray saved successfully")
	}

	return nil
}
*/

//当聊天socket连接结束时，保存数据到用户应用数据表
func DpsAddAppDataWSClose(appId int64, uid, dpid string) error {
	//获取最新的聊天记录,并从聊天记录数组中获取最后一条
	latestChatBot, err := datasource.GetChatHistoryRecordLatest(uid, dpid, utils.Strval(appId))
	if err != nil {
		fmt.Println(config.ColorRed, "获取最新的数字人聊天记录失败", err, config.ColorReset)
		//ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "获取最新的数字人聊天记录失败"})
		return errors.New("获取最新的数字人聊天记录失败")
	}
	userId, err := strconv.ParseInt(uid, 10, 64)
	if err != nil {
		//ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户id失败"})
		return errors.New("用户id转换失败")
	}
	AppData, err := json.Marshal(latestChatBot.Status)
	if err != nil {
		fmt.Println("转换为JSON时出错：", err)
		//ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "转换为JSON时出错"})
		return errors.New("转换为JSON时出错")
	}
	appStatusData := string(AppData)
	if appId != 0 {
		var userAppData = models.UserApplicationData{
			AppId:      appId,
			UserId:     userId,
			StatusData: appStatusData,
			CreatedAt:  time.Now().Unix(),
			UpdatedAt:  time.Now().Unix(),
		}
		err = models.CreateUserApplication(&userAppData)
		if err != nil {
			fmt.Println("添加用户应用数据失败：", err)
			//ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "添加用户应用数据失败"})
			return errors.New("添加用户应用数据失败")
		}
	}

	//ctx.JSON(http.StatusOK, gin.H{"code": 1, "message": "添加用户应用数据成功"})
	return nil
}
