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"
	"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 SendMsg struct {
	Type    int    `json:"type"`
	Content string `json:"content"`
}

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

type HuaSoulReplyMsg struct {
	Code         int                    `json:"code"`
	Status       map[string]interface{} `json:"status"`
	ISLIU        string                 `json:"ISLIU"`
	ResponseName string                 `json:"responseName"`
	ResponseDpId int64                  `json:"responseDpId"`
	Muse         int                    `json:"muse"`
}

/*
构建Client表
*/
//Id|Uid|Did|title|descript
type Client struct {
	AppId        int64
	UUID         string
	Conversation *models.Conversation
	Socket       *websocket.Conn
	Send         chan *HuaSoulEchoRespones
	DpName       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 ClientManager struct {
	Clients map[string]*Client
	//Broadcast  chan *Broadcast
	Reply      chan *Client
	Register   chan *Client
	Unregister chan *Client
}

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

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

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

func WsHandler(ctx *gin.Context) {
	/*
	   从session里获取用户id
	*/
	session := sessions.Default(ctx)
	userId := session.Get("UserID")
	fmt.Println("chat session UserID：", userId)
	/*
	 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
	}

	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)
		}
	}
	ws_uid := ctx.Query("id")

	var SP *models.ServiceProvider
	// 服务商id获取
	ServiceProviderId := ctx.Query("AuthId")
	if ServiceProviderId != "" {
		SP, err = models.GetServiceProviderById(ServiceProviderId)
		if err != nil {
			fmt.Println("根据服务商id查询出错:", err)
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "根据服务商id查询服务商出错"})
			return
		}
		if SP == nil {
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "非法的服务商"})
			return
		}
	}

	if userId == nil {
		// 处理session中未找到值的情况，返回错误信息
		/*这里是双保险为了测试用*/
		if ws_uid != "" {
			userId = ws_uid
		}
		/*if SP != nil {
			userId = utils.Strval(SP.Uid)
		}*/
		if userId == nil {
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "Session中未找到用户ID,用户未登录"})
			fmt.Println(config.ColorYellow, "Session中未找到用户ID,用户未登录", config.ColorReset)
			return
		}
	}
	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.ParseInt(user_Id, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "数字人id类型转换出错"})
		//continue
		return
	}

	if ws_uid == "" && ServiceProviderId == "" {
		fmt.Println(config.ColorPurple, "用户id或者服务商id为空", config.ColorReset)
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户id或者服务商id为空"})
		return
	}
	// webSocket 数字人id
	digital_Id := ctx.Query("DpId")
	UUID := ctx.Query("uuid")

	dp_Id, _ := strconv.Atoi(digital_Id)
	//查询数据库，根据数字人Id查询数字人信息
	digitalPerson, err := models.GetDigitalPersonByID(int64(dp_Id))
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户与数字人创建会话时，查询数字人失败"})
		log.Println(err.Error())
		return
	}
	//if SP.InspirationValue == 0 {
	//	ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "服务商的灵感值余额不足，无法进行数字人聊天"})
	//	return
	//}

	//从session中获取用户id
	/*
	   判断用户是否登录
	*/
	if b || SP != nil {

		//fmt.Println(digitalPerson)
		//ctx.JSON(http.StatusOK, gin.H{"code": 1, "message": "用户与数字人创建会话时，查询数字人", "digitalPerson": digitalPerson})
		// 根据用户id和数字人id，查询会话表中是否有会话记录
		var conversation *models.Conversation
		if appId != "" {
			//app_id
			conversation, err = models.GetConversationsByUserIdAndDpId(uid, int64(dp_Id), app_id)
			if err != nil {
				ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "查询会话记录失败！"})
				return
			}
		} else {
			//如果前端没有传AppId
			app_id = 0
			conversation, err = models.GetConversationsByUserIdAndDpId(uid, int64(dp_Id), 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)*/

				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": "创建调用数字人会话接口实例，失败！"})
				}

				conversation = &models.Conversation{
					Uid:     uid,
					DpId:    int64(dp_Id),
					Title:   "用户Id为" + user_Id + "的用户和数字人" + digitalPerson.Name + "开始会话",
					IsliuId: ISULU_ID,
				}

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

			} else {
				//如果前端没有传uuid，参数个数为1
				apiCode, ISULU_ID, err := HuaSoulNewAPI(digital_Id)
				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": "创建调用数字人会话接口实例，失败！"})

				}
				fmt.Println("ISULU_ID: ", ISULU_ID)
				conversation = &models.Conversation{
					Uid:     uid,
					DpId:    int64(dp_Id),
					Title:   "用户Id为" + user_Id + "的用户和数字人" + digitalPerson.Name + "开始会话",
					IsliuId: ISULU_ID,
				}
				if appId == "" {
					conversation.AppId = 0
				} else {
					conversation.AppId = app_id
				}

				/*
				 往mysql数据库的会话表中插入一条记录
				*/
				err = models.InsertConversation(conversation)
				if err != nil {
					ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "创建会话后，向数据库插入数据失败！"})
					return
				}

			}

		} else {
			ISULU_ID = conversation.IsliuId
			//NewConversation = *conversation
			// 如果查询到记录，调用查询意识流Id接口判断意识流id是否有效，若无效则修改意识流ID为新的意识流ID
			flag := HuaSoulFindISLIUID(conversation.IsliuId)
			fmt.Println("查询意识流Id, flag: ", flag)
			//没找到
			if !flag {
				//创建调用AI接口实例
				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)
					*/

					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": "创建调用数字人会话接口实例，失败！"})

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

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

				} else {

					//UUID为空时候，只传一个参数即可
					apiCode, ISULU_ID, err := HuaSoulNewAPI(digital_Id)
					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": "创建调用数字人会话接口实例，失败！"})

					}
					// 把调用AI接口获取的意识流ID赋给conversation.IsliuId
					conversation.IsliuId = ISULU_ID
					if appId == "" {
						conversation.AppId = 0
					} else {
						conversation.AppId = app_id
					}
					//更新数据库中会话表对应会话的意识流id
					err = models.UpdateConversation(conversation)

					if err != nil {
						ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "更新会话意识流id失败！"})
						return
					}

				}

			}

		}

		//根据uid查询用户来源是否为咪咕
		user, err := models.GetUserByID(conversation.Uid)
		if err != nil {
			ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "根据用户id查询用户出错！"})
			return
		}

		// 创建一个用户客户端会话实例
		newClient := &Client{
			AppId:        app_id,
			UUID:         UUID,
			Conversation: conversation,
			Socket:       conn,
			Send:         nil,
			DpName:       digitalPerson.Name,
			AuthId:       ServiceProviderId,
		}
		if user != nil && user.RegisteredSource != "" {
			newClient.UserSource = user.RegisteredSource
		}
		// 用户会话注册到用户管理上
		Manager.Register <- newClient

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

		url := config.Conf.SoulUrl + "/soul/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.Read()
		//go newClient.Write()

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

}

func DestroyWs(c *Client) { // 避免忘记关闭，所以要加上close
	/*
	   当聊天socket连接结束时，保存用户的应用数据到用户应用数据表
	*/
	strUid := utils.Strval(c.Conversation.Uid)
	strDpId := utils.Strval(c.Conversation.DpId)
	if strUid == "" || strDpId == "" || c.AppId == 0 {
		fmt.Println(config.ColorRed, "用户id或者数字人id为空!", 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)
			}

		}
	}

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

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

	// 构造请求参数
	request := SoulNeuralRequest{
		Auth:    config.Conf.SoulAuth,
		Type:    0, // 0表示下载
		ISLIUid: c.Conversation.IsliuId,
	}
	// 调用函数
	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 *Client) Read() {
	//延迟关闭websocket
	defer DestroyWs(c)
	/*
	  死循环执行websocket消息接收和发送
	*/
	//var SP *models.ServiceProvider
	for {
		c.Socket.PongHandler()
		sendMsg := new(SendMsg)
		err := c.Socket.ReadJSON(&sendMsg)
		if err != nil {
			log.Println("数据格式不正确", err)
			// 向前端返回数据格式不正确的状态码和消息
			errorMsg := ErrorMessage{
				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)
			//剔除注册的客户端用户
			Manager.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)
			conversation_Id := utils.Strval(c.Conversation.Uid) + "_" + utils.Strval(c.Conversation.DpId) + "_" + utils.Strval(c.Conversation.AppId)

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

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

					}

				}

				return
			}

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

			if ISLIU == "" || status == nil {
				log.Println("会话意识流为空...")
				// 向前端返回数据格式不正确的状态码和消息
				errorMsg := ErrorMessage{
					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.Conversation.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 := HuaSoulReplyMsg{
					Code:         resCode,
					Status:       status,
					ISLIU:        ISLIU,
					ResponseDpId: c.Conversation.DpId,
					ResponseName: c.DpName,
					Muse:         Muse,
				}
				msg, _ := json.Marshal(HSReplyMsg)
				write_err := c.Socket.WriteMessage(websocket.TextMessage, msg)
				if write_err != nil {
					log.Println("返回意识流给客户端时出错! ")
					DestroyWs(c)
					return
				}
				/*
				   mongoDB保存数字人发送给前端用户的聊天记录
				*/

				senderType2 := "bot"
				chatDB_err2 := datasource.SaveChatRecordMongoDB(conversation_Id, c.Conversation.DpId, 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.Conversation.DpId)
					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实例
							AuthLogRecord := models.InspirationUsageLog{
								AuthId:              sp.ID,
								DpId:                c.Conversation.DpId,
								DpName:              c.DpName,
								ChatTime:            time.Now().Unix(), // 使用相应的时间戳
								InspirationConsumed: museNum,
							}

							// 调用函数添加记录
							_, err = models.AddInspirationUsageLog(&AuthLogRecord)
							if err != nil {
								log.Printf("添加服务商灵感使用记录失败: %v", err)
							} else {
								log.Println(config.ColorBlue, "添加服务商灵感使用记录成功", config.ColorReset)
							}
							/* 更新服务商的灵感值 */
							if museNum > sp.InspirationValue {
								// 处理错误或返回
								fmt.Println("服务商灵感值不足本次扣除")
								return
							}
							sp.InspirationValue = sp.InspirationValue - museNum
							sp.TotalInspiration = sp.TotalInspiration + museNum
							err := models.UpdateServiceProviderColsMuse(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 := HuaSoulReplyMsg{
					Code:         resCode,
					Status:       status,
					ISLIU:        ISLIU,
					ResponseDpId: c.Conversation.DpId,
					ResponseName: c.DpName,
					Muse:         Muse,
				}

				//解析AI接口返回的数据
				msg, _ := json.Marshal(HSReplyMsg)

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

				senderType := "bot"
				chatDB_err := datasource.SaveChatRecordMongoDB(conversation_Id, c.Conversation.DpId, 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)
					DestroyWs(c)
					return
				}
				/*
				  发送消息成功，resCode为1
				*/
				if resCode == 1 {
					//增加数字人的交互量
					err := models.IncrementDigitalPersonInteractionCount(c.Conversation.DpId)
					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)
							// 构建一个InspirationUsageLog实例
							AuthLogRecord := models.InspirationUsageLog{
								AuthId:              sp.ID,
								DpId:                c.Conversation.DpId,
								DpName:              c.DpName,
								ChatTime:            time.Now().Unix(), // 使用相应的时间戳
								InspirationConsumed: museNum,
							}

							// 调用函数添加记录
							_, err = models.AddInspirationUsageLog(&AuthLogRecord)
							if err != nil {
								log.Printf("添加服务商灵感使用记录失败: %v", err)
							} else {
								log.Println(config.ColorBlue, "添加服务商, AI调用，灵感使用记录成功", config.ColorReset)
							}
							/* 更新服务商的灵感值 */
							if int64(echoResponse.MuseValue) > sp.InspirationValue {
								// 处理错误或返回
								fmt.Println("服务商灵感值不足本次扣除")
								return
							}

							sp.InspirationValue = sp.InspirationValue - museNum
							sp.TotalInspiration = sp.TotalInspiration + museNum
							err := models.UpdateServiceProviderColsMuse(sp)
							if err != nil {
								log.Println(config.ColorRed, "更新服务商灵感消耗值失败:", err, config.ColorReset)
								return
							} else {
								log.Println(config.ColorBlue, "更新服务商灵感消耗值成功,剩余灵感值:", sp.InspirationValue, config.ColorReset)
							}
						}

					}
				}
			}
		}()

	}

}

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

func (c *Client) Write() {
	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.Conversation.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 AddAppDataWSClose(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
}
