package service

import (
	"WorldEpcho/src/config"
	"WorldEpcho/src/models"
	"WorldEpcho/src/utils"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

//创建数字人API接口时候返回的响应体
type HuaSoulEchoRespones struct {
	Code       int                    `from:"code" json:"code"`
	Status     map[string]interface{} `from:"status" json:"status"`
	ISLIU      string                 `from:"ISLIU" json:"ISLIU"`
	MuseValue  int                    `json:"muse"`
	SenderDpId int64                  `json:"senderDpId"`
}

func (client *Client) HuaSoulEchoAPI(msg *SendMsg, uuid string) (*HuaSoulEchoRespones, error) {
	/*
	   创建一个请求参数对象
	*/
	EchoReustParam := models.EchoChatParm{
		Auth:    config.Conf.SoulAuth, //配置文件读取服务商认证码
		Type:    msg.Type,
		IsliuId: client.Conversation.IsliuId,
		Content: msg.Content,
	}
	//从缓存中获取应用名称和用户信息模板
	var name, template, isPassMHT string
	if uuid != "" {
		if AppCache[uuid] != nil {
			isPassMHT = AppCache[uuid].IsPassMHT
			name = AppCache[uuid].AppName
			template = AppCache[uuid].UserInfoTemplate
		}
	}
	if name != "" && template != "" {
		appinfo := models.EchoAppInfo{
			AppName:          name,
			UserInfoTemplate: template,
		}
		// 将结构体转换为 JSON 格式
		jsonData, err := json.Marshal(appinfo)
		if err != nil {
			fmt.Println("Error converting to JSON:", err)
		}
		// 将字节切片转换为字符串并打印
		jsonString := string(jsonData)
		//fmt.Println("AppInfo: ", jsonString)
		//如果app信息不为空，赋值给请求参数对象
		if isPassMHT == "no" {
			EchoReustParam.AppInfo = jsonString
		}
	}

	fmt.Println("EchoRequestParam: ", EchoReustParam)
	request_url := config.Conf.SoulUrl + "/soul/echo"
	fmt.Println("Echo request_url", request_url)

	// 准备POST请求的body数据，这里使用bytes.Buffer来构建一个简单的JSON格式数据作为示例
	//requestBody := []byte(`{"key1": "value1", "key2": "value2"}`)
	/*
		requestBody, err := json.Marshal(ChatRequestParam)
		if err != nil {
			fmt.Println("Failed to marshal request body:", err)
			return -1, "请求参数体，解析失败", "解析chatParam参数失败，无法获取意识流"
		}
	*/
	postData := url.Values{}
	postData.Add("auth", EchoReustParam.Auth)
	postData.Add("type", strconv.Itoa(EchoReustParam.Type))
	postData.Add("ISLIUid", EchoReustParam.IsliuId)
	postData.Add("content", EchoReustParam.Content)
	if EchoReustParam.AppInfo != "" && isPassMHT == "no" && EchoReustParam.Type == 1 {
		postData.Add("appInfo", EchoReustParam.AppInfo)
	}
	// 发送POST请求
	resp, err := http.Post(request_url, "application/x-www-form-urlencoded", strings.NewReader(postData.Encode()))
	if err != nil {
		fmt.Println("会话响应失败，请稍后重试:", err)
		return nil, err
	}

	defer resp.Body.Close()

	fmt.Println("Response status:", resp.Status)

	// 读取响应的body数据
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("读取会话响应数据失败，请稍后重试:", err)
		return nil, err
	}
	// 解析JSON
	var response HuaSoulEchoRespones

	err = json.Unmarshal(body, &response)

	// 将JSON打印为字符串
	fmt.Println("收到的响应:", string(body))

	if err != nil {
		fmt.Println("数字人调用会话接口失败，无法获取意识流:", err)
		return nil, fmt.Errorf("调用会话接口失败无法获取意识流")
	}
	if response.Code == 1 {
		response.SenderDpId = client.Conversation.DpId
		if AppCache[uuid] != nil {
			AppCache[uuid].IsPassMHT = ""
		}

	}
	// 使用解析后的参数
	fmt.Println("Code: ", response.Code)
	fmt.Println("response.Status: ", response.Status)
	fmt.Println("response.ISLIU: ", response.ISLIU)
	fmt.Println("response.MuseValue", response.MuseValue)

	return &response, nil

}

func (clients *Clients) DpsHuaSoulEchoAPI(msg *DpsSendMsg) (*HuaSoulEchoRespones, error) {
	/*
	   创建一个请求参数对象
	*/
	ChatRequestParam := models.DpsEchoChatParm{
		Auth: config.Conf.SoulAuth, //配置文件读取服务商认证码
		Type: msg.Type,
		//IsliuId: IsliuIds[sliceIndex],
		//Content: msg.Content,
	}

	IsliuIds := make([]string, len(clients.DpConversations.IsliuIds))
	// DpNames := make([]string, len(clients.DpNames))
	copy(IsliuIds, clients.DpConversations.IsliuIds)

	fmt.Println("IsliuIds : ", IsliuIds)
	// copy(DpNames, clients.DpNames)
	//如果最后发送者意识流id不为空,上次聊天的数字人索引不为-1，剔除上一次的意识流id
	if clients.LastIndex != -1 {
		IsliuIds = utils.RemoveString(IsliuIds, clients.DpConversations.IsliuIds[clients.LastIndex])
		// DpNames = utils.RemoveString(clients.DpNames, clients.DpNames[clients.LastIndex])
	}
	fmt.Println("IsliuIds 数组长度: ", len(IsliuIds))
	randomIndex, err := utils.RandomIDFromSlice(len(IsliuIds))
	if err != nil {
		return nil, err
	}
	// 随机抽取一个数字人的意识流id, 给请求体对象赋值
	ChatRequestParam.IsliuId = IsliuIds[randomIndex]
	// 获取随机抽取的数字人意识流id对应的下标索引
	indexOf, err := utils.IndexOf(clients.DpConversations.IsliuIds, IsliuIds[randomIndex])
	if err != nil {
		return nil, err
	}
	fmt.Println("获取随机抽取的数字人意识流id对应的下标索引: ", indexOf, "dpId: ", clients.DpConversations.DpIds[indexOf], " IsliuIds[randomIndex] ==> : ", IsliuIds[randomIndex])
	//不是首次会话，保存上一次的回复消息的数字人的索引下标
	if clients.LastIndex == -1 {
		clients.LastIndex = indexOf
	}

	// 判断是不是数字人之间进行交互
	if msg.Type == 1 && clients.LastMsg != "" {
		ChatRequestParam.Content = clients.LastMsg
		ChatRequestParam.Sender = clients.DpNames[clients.LastIndex]

	} else {
		ChatRequestParam.Content = msg.Content
		ChatRequestParam.Sender = ""

	}
	//判断用户是否插话，且用户的消息不为空
	if msg.Type == 0 && msg.Content != "" {
		isContains := utils.ContainsName(clients.DpNames, msg.Content)
		if isContains {
			UserMsg := msg.Content + "(回答这句话在向谁提问，只写名字)"
			fmt.Println("用户插话的消息内容: ", UserMsg)
			//对用户的语义进行分析
			DpName, err := SendSemanticAnalysisRequest(UserMsg)
			if err != nil {
				fmt.Println("解析用户消息语义出错:", err)
				return nil, err
			}
			if DpName == "" {
				ChatRequestParam.IsliuId = IsliuIds[randomIndex]

			} else {
				fmt.Println("用户指定回答问题的数字人名称为: ", DpName)
				DpName_index, err := utils.IndexOf(clients.DpNames, DpName)
				if err != nil {
					return nil, err
				}
				fmt.Println("被提问的数字人下标索引: ", DpName_index)
				if DpName_index != -1 {
					indexOf, err = utils.IndexOf(clients.DpConversations.IsliuIds, clients.DpConversations.IsliuIds[DpName_index])
					if err != nil {
						return nil, err
					}
					ChatRequestParam.IsliuId = clients.DpConversations.IsliuIds[indexOf]
				}
			}
		}

	}

	request_url := config.Conf.SoulUrl + "/soul/echo"
	fmt.Println("Echo request_url", request_url)

	// 准备POST请求的body数据，这里使用bytes.Buffer来构建一个简单的JSON格式数据作为示例
	//requestBody := []byte(`{"key1": "value1", "key2": "value2"}`)
	/*
		requestBody, err := json.Marshal(ChatReustParam)
		if err != nil {
			fmt.Println("Failed to marshal request body:", err)
			return -1, "请求参数体，解析失败", "解析chatParam参数失败，无法获取意识流"
		}
	*/
	postData := url.Values{}
	postData.Add("auth", ChatRequestParam.Auth)
	postData.Add("type", strconv.Itoa(ChatRequestParam.Type))
	postData.Add("ISLIUid", ChatRequestParam.IsliuId)
	postData.Add("Sender", ChatRequestParam.Sender)
	postData.Add("content", ChatRequestParam.Content)
	fmt.Printf(" 【 ChatRequestParam 】==> Type:%d , ISLIUid: %s , Sender: %s  , Content: %s ,\n", ChatRequestParam.Type, ChatRequestParam.IsliuId, ChatRequestParam.Sender, ChatRequestParam.Content)
	// 发送POST请求
	resp, err := http.Post(request_url, "application/x-www-form-urlencoded", strings.NewReader(postData.Encode()))
	if err != nil {
		fmt.Println("会话响应失败，请稍后重试:", err)
		return nil, err
	}

	defer resp.Body.Close()

	fmt.Println(config.ColorGreen, "Response status:", resp.Status, config.ColorReset)

	// 读取响应的body数据
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("读取会话响应数据失败，请稍后重试:", err)
		return nil, err
	}
	// 解析JSON
	var response HuaSoulEchoRespones

	err = json.Unmarshal(body, &response)

	// 将JSON打印为字符串
	fmt.Println("收到的响应:", string(body))

	if err != nil {
		fmt.Println("数字人调用会话接口失败，无法获取意识流:", err)
		return nil, fmt.Errorf("调用会话接口失败无法获取意识流")
	}

	if response.Code == 1 {
		clients.LastIndex = indexOf
		clients.LastMsg = response.ISLIU
		fmt.Println(config.ColorPurple, "==== LastMsg : === ", clients.LastMsg, "=== LastIndex :===", clients.LastIndex, config.ColorReset)
		//Type == 1 数字人发起会话
		if msg.Type == 1 {
			ChatRequestParam.Sender = clients.DpNames[indexOf]
			fmt.Println("Type为1 随机抽取数字人回复: Sender", ChatRequestParam.Sender)
		}
	}
	// 使用解析后的参数
	fmt.Println("Code: ", response.Code)
	fmt.Println("response.Status: ", response.Status)
	fmt.Println("response.ISLIU: ", response.ISLIU)

	return &response, nil

}
