package service

import (
	"WorldEpcho/src/config"
	database "WorldEpcho/src/datasource"
	"WorldEpcho/src/models"
	"WorldEpcho/src/utils"
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
	"time"
)

var (
	ColorReset  = "\033[0m"
	ColorYellow = "\033[33m"
)

// WorldCreateRequest 定义了创建世界时发送的请求体的结构体

type WorldCreateRequest struct {
	Auth     string                 `json:"auth"`
	Name     string                 `json:"name"`
	BgInfo   string                 `json:"BgInfo"`
	UserInfo map[string]interface{} `json:"userInfo"`
}

// WorldCreateResponse 定义了创建世界时接受的响应体的结构体
type WorldCreateResponse struct {
	Code              int                    `json:"code"`
	ISLIUid           string                 `json:"ISLIUid"`
	WObj              map[string]interface{} `json:"WObj"`
	ISLIU             string                 `json:"ISLIU"`
	MessageStatusType string                 `json:"messageStatusType,omitempty"` // Optional field to indicate message type
}

// CreateWorld 是向指定的地址发送创建世界请求的函数
func NewWorld(url string, request WorldCreateRequest) (*WorldCreateResponse, error) {
	// 将请求体编码为 JSON
	requestBody, err := json.Marshal(request)
	if err != nil {
		return nil, fmt.Errorf("failed to encode request body: %w", err)
	}

	fmt.Printf(" 【 ****************** 发送请求... ==>  new world IsLIUId, url:%s  **************** 】", url)
	NewWorldStartTime := time.Now()
	// 创建 POST 请求
	resp, err := http.Post(url, "application/json", bytes.NewBuffer(requestBody))
	if err != nil {
		return nil, fmt.Errorf("failed to send request: %w", err)
	}
	defer resp.Body.Close()

	// 读取和解码响应体
	var response WorldCreateResponse
	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read response body: %w", err)
	}
	err = json.Unmarshal(respBody, &response)
	if err != nil {
		return nil, fmt.Errorf("failed to decode response body: %w", err)
	}

	fmt.Println(config.ColorBlue, "New world API Code:", response.Code, "code为1成功 0服务失效 3信息格式有误 4非法的服务商", config.ColorReset)
	if response.Code == 1 {
		NewWorldStartTimeDuration := time.Since(NewWorldStartTime)
		fmt.Println(" ==================================================================    ")
		fmt.Printf(ColorYellow+"【 ****************** 请求成功响应... ==>  new world IsLIUId, url:%s  **************** 】"+ColorReset+"\n", url)

		log.Printf(" 【=== 响应成功耗时 : %s\n ===】", NewWorldStartTimeDuration.String())

		if len(response.WObj) == 0 && strings.Contains(response.ISLIU, "【任务提示】") {
			response.MessageStatusType = "prologue"
		}
	}
	return &response, nil
}

// 创建虚拟世界控制器
/*
func CreateVirtualWorldHandler(uid int64, name, BgInfo, userInfo string) (*WorldCreateResponse, error) {

	//获取服务商凭证
	auth := config.Conf.SoulAuth
	// 将JSON字符串转换为字节切片
	fmt.Println("userInfo: ", userInfo)
	jsonDataBytes := []byte(userInfo)
	//fmt.Println("jsonDataBytes: ", jsonDataBytes)
	// 定义map接收解析后的数据
	var UserInfo map[string]interface{}

	// 解析JSON数据到map
	if err := json.Unmarshal(jsonDataBytes, &UserInfo); err != nil {
		fmt.Println("用户json信息解析失败", err)
		return nil, err
	}

	var worldCreateRequest = WorldCreateRequest{
		Auth:     auth,
		Name:     name,
		BgInfo:   BgInfo,
		UserInfo: UserInfo,
	}
	fmt.Println("创建世界的参数请求体：", worldCreateRequest)
	//请求url
	quest_url := config.Conf.SoulUrl + "/world/new"
	//quest_url := "http://192.168.2.239:13679/world/new"
	response, err := NewWorld(quest_url, worldCreateRequest)
	if err != nil {
		fmt.Println("Error creating world:", err)
		return nil, err
	}
	//根据世界名称查询世界对象是否存在
	wordInfo, err := models.GetWorldInfoByName(name)
	if err != nil {
		return nil, errors.New("根据世界名称查询世界对象出错")
	}
	// 声明临时变量保存世界id
	var worldId int64
	if wordInfo == nil {
		//在世界信息表中创建世界的相关信息
		// 创建一个新的世界信息实例
		newWorld := models.WorldInfo{
			Name:       name,
			Background: BgInfo,
			CreatedAt:  time.Now().Unix(),
		}
		wId, err := models.AddWorldInfo(&newWorld)
		if err != nil {
			return nil, errors.New("创建世界信息出错")
		}
		worldId = wId
	} else {
		worldId = wordInfo.ID
	}
	//根据用户id和世界名称查询会话是否存在
	wc, conver_exist, err := models.GetWorldConversationByUidAndWorldName(uid, name)
	if err != nil {
		return nil, errors.New("根据用户id和世界名称查询会话出错")
	}

	//byName, err := models.GetWorldInfoByName(name)
	if response.Code == 1 {
		//如果会话不存在，创建对应的世界流会话
		if !conver_exist {
			//创建世界成功，保存相关信息到数据库
			// 创建一个世界会话的实例
			title := "id为" + utils.Strval(uid) + "的用户在" + name + "的世界中聊天"
			newWorldconversation := models.WorldConversation{
				Uid:       uid,
				IsLiuId:   response.ISLIUid,
				WorldId:   worldId,
				WorldName: name,
				Title:     title,
				BgInfo:    BgInfo,
				UserInfo:  userInfo,
			}
			// 调用AddWorld函数添加新的世界
			err = models.AddWorldConversation(newWorldconversation)
			if err != nil {
				log.Fatal("添加世界流会话失败:", err)
				return nil, errors.New("添加世界流会话失败")
			}
		} else {
			//如果已经存在世界流会话了，则更新意识流id
			wc.IsLiuId = response.ISLIUid
			err := models.UpdateWorldConversation(wc)
			if err != nil {
				return nil, errors.New("更新世界意识流id失败")
			}
		}

		//c.JSON(http.StatusOK, gin.H{"code": 1, "message": "创建虚拟世界成功"})
	}

	// 打印响应结果
	fmt.Println("world Response Code:", response.Code)
	fmt.Println("world ISLIUid:", response.ISLIUid)
	fmt.Println("world WObj:", response.WObj)
	fmt.Println("world ISLIU:", response.ISLIU)

	return response, nil
}
*/

func CreateVirtualWorldHandler(uid int64, name, BgInfo, userInfo string) (*WorldCreateResponse, *models.WorldConversation, error) {

	//获取服务商凭证
	auth := config.Conf.SoulAuth
	// 将JSON字符串转换为字节切片
	fmt.Println("userInfo: ", userInfo)
	jsonDataBytes := []byte(userInfo)
	//fmt.Println("jsonDataBytes: ", jsonDataBytes)
	// 定义map接收解析后的数据
	var UserInfo map[string]interface{}

	// 解析JSON数据到map
	if err := json.Unmarshal(jsonDataBytes, &UserInfo); err != nil {
		fmt.Println("用户json信息解析失败", err)
		return nil, nil, err
	}
	//根据世界名称查询世界对象是否存在
	wordInfo, err := models.GetWorldInfoByName(name)
	if err != nil {
		return nil, nil, errors.New("根据世界名称查询世界对象出错")
	}

	var worldCreateRequest = WorldCreateRequest{
		Auth:     auth,
		BgInfo:   BgInfo,
		UserInfo: UserInfo,
	}
	if ContainsString(wordInfo.Tags, "业务经理考核系统") {
		worldCreateRequest.Name = "定制考核"
	} else {
		worldCreateRequest.Name = name
	}
	fmt.Println("创建世界的参数请求体：", worldCreateRequest)

	//请求url
	quest_url := config.Conf.SoulUrl + "/world/new"
	//quest_url := "http://192.168.2.239:13679/world/new"
	response, err := NewWorld(quest_url, worldCreateRequest)
	if err != nil {
		fmt.Println("Error creating world:", err)
		return nil, nil, err
	}
	//开启事务
	session := database.Engine.NewSession()
	defer session.Close() //延迟关闭session
	err = session.Begin()
	if err != nil {
		fmt.Println("开启事务失败")
		return nil, nil, errors.New("开启事务失败")
	}

	// 声明临时变量保存世界id
	var worldId int64
	if wordInfo == nil {
		//在世界信息表中创建世界的相关信息
		// 创建一个新的世界信息实例
		newWorld := models.WorldInfo{
			Name:       name,
			Background: BgInfo,
			CreatedAt:  time.Now().Unix(),
		}
		wId, err := models.AddWorldInfo(session, &newWorld)
		if err != nil {
			return nil, nil, errors.New("创建世界信息出错")
		}
		worldId = wId
	} else {
		worldId = wordInfo.ID
	}
	//根据用户id和世界名称查询会话是否存在
	wc, conver_exist, err := models.GetWorldConversationByUidAndWorldName_Tx(session, uid, name)
	if err != nil {
		return nil, nil, errors.New("根据用户id和世界名称查询会话出错")
	}
	var newWorldconversation models.WorldConversation
	//byName, err := models.GetWorldInfoByName(name)
	if response.Code == 1 {

		//如果会话不存在，创建对应的世界流会话
		if !conver_exist {
			//创建世界成功，保存相关信息到数据库
			// 创建一个世界会话的实例
			title := "id为" + utils.Strval(uid) + "的用户在" + name + "的世界中聊天"

			newWorldconversation.Uid = uid
			newWorldconversation.IsLiuId = response.ISLIUid
			newWorldconversation.WorldId = worldId
			newWorldconversation.WorldName = name
			newWorldconversation.Title = title
			newWorldconversation.BgInfo = BgInfo
			newWorldconversation.UserInfo = userInfo

			// 调用AddWorld函数添加新的世界
			err = models.AddWorldConversation(session, &newWorldconversation)
			if err != nil {
				fmt.Println("添加世界流会话失败:", err)
				return nil, nil, errors.New("添加世界流会话失败")
			}
			//return response, &newWorldconversation, nil
		} else {
			//如果已经存在世界流会话了，则更新意识流id
			wc.IsLiuId = response.ISLIUid
			newWorldconversation = *wc // 将已存在的会话对象赋值给newWorldconversation
			err := models.UpdateWorldConversation(session, wc)
			if err != nil {
				return nil, nil, errors.New("更新世界意识流id失败")
			}
		}

		//c.JSON(http.StatusOK, gin.H{"code": 1, "message": "创建虚拟世界成功"})
	}
	//提交事务
	err = session.Commit()
	if err != nil {
		//ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "创建数字人失败! "})
		return nil, nil, nil
	}
	// 打印响应结果
	fmt.Println("world Response Code:", response.Code)
	fmt.Println("world ISLIUid:", response.ISLIUid)
	fmt.Println("world WObj:", response.WObj)

	fmt.Println("world ISLIU:", response.ISLIU)
	fmt.Println("world MessageStatusType:", response.MessageStatusType)

	return response, &newWorldconversation, nil

}

func MiGuCreateVirtualWorldHandler(uid, wid int64, BgInfo, userInfo string) (*WorldCreateResponse, *models.WorldConversation, error) {
	// 创建世界开始时间
	//createWorldStartTime := time.Now()
	//fmt.Println(config.ColorGreen, "=================【 开始请求模型端创建世界接口.... 】 =================", config.ColorReset)
	//获取服务商凭证
	auth := config.Conf.SoulAuth
	// 将JSON字符串转换为字节切片
	fmt.Println("userInfo: ", userInfo)
	jsonDataBytes := []byte(userInfo)
	//fmt.Println("jsonDataBytes: ", jsonDataBytes)
	// 定义map接收解析后的数据
	var UserInfo map[string]interface{}

	// 解析JSON数据到map
	if err := json.Unmarshal(jsonDataBytes, &UserInfo); err != nil {
		fmt.Println("用户json信息解析失败", err)
		return nil, nil, err
	}
	var worldName string
	//根据世界名称查询世界对象是否存在
	wordInfo, _, err := models.GetWorldInfoById(wid)
	if err != nil {
		return nil, nil, errors.New("根据世界名称查询世界对象出错")
	}
	if wordInfo == nil {
		return nil, nil, errors.New("世界信息不存在")
	}
	worldName = wordInfo.Name

	var worldCreateRequest = WorldCreateRequest{
		Auth:     auth,
		BgInfo:   BgInfo,
		UserInfo: UserInfo,
	}
	if ContainsString(wordInfo.Tags, "业务经理考核系统") {
		worldCreateRequest.Name = "定制考核"
	} else {
		worldCreateRequest.Name = worldName
	}
	fmt.Println("创建世界的参数请求体：", worldCreateRequest)

	//请求url
	quest_url := config.Conf.SoulUrl + "/world/new"
	//quest_url := "http://192.168.2.239:13679/world/new"

	//fmt.Println(config.ColorGreen, "=================【 开始请求模型端创建世界接口.... 】 =================", config.ColorReset)
	//startNewWorldAPITime := time.Now() // 记录 startNewWorldAPITime 调用模型服务端接口执行创建世界前的时间
	response, err := NewWorld(quest_url, worldCreateRequest)
	if err != nil {
		fmt.Println("Error creating world:", err)
		return nil, nil, err
	}
	//fmt.Println(config.ColorGreen, "=================【 请求模型端创建世界接口...结束. 】 =================", config.ColorReset)

	//NewWorldAPIDuration := time.Since(createWorldStartTime) // 计算 NewWorld 函数执行时间
	// 计算整个函数执行的总时间
	// log.Printf("【 === 调用模型端创建世界接口,耗费时间: %s\n ==】", NewWorldAPIDuration.String())

	//开启事务
	session := database.Engine.NewSession()
	defer session.Close() //延迟关闭session
	err = session.Begin()
	if err != nil {
		fmt.Println("开启事务失败")
		return nil, nil, errors.New("开启事务失败")
	}

	// 声明临时变量保存世界id
	var worldId int64
	if wordInfo == nil {
		//在世界信息表中创建世界的相关信息
		// 创建一个新的世界信息实例
		newWorld := models.WorldInfo{
			Name:       worldName,
			Background: BgInfo,
			CreatedAt:  time.Now().Unix(),
		}
		wId, err := models.AddWorldInfo(session, &newWorld)
		if err != nil {
			return nil, nil, errors.New("创建世界信息出错")
		}
		worldId = wId
	} else {
		worldId = wordInfo.ID
	}
	//根据用户id和世界名称查询会话是否存在
	wc, conver_exist, err := models.GetWorldConversationByUidAndWorldId_Tx(session, uid, wid)
	if err != nil {
		return nil, nil, errors.New("根据用户id和世界名称查询会话出错")
	}
	var newWorldconversation models.WorldConversation
	//byName, err := models.GetWorldInfoByName(name)

	//responseNewWorldAPI_Time1 := time.Now() // 记录调用模型端创建世界响应时间
	if response.Code == 1 {

		//responseCode1Time1 := time.Since(createWorldStartTime)
		//fmt.Println(" ==================================================================    ")
		//log.Printf(" 【=== 调用模型端创建世界接口,响应 response.Code == 1 耗费时间: %s\n ===】", responseCode1Time1.String())
		//如果会话不存在，创建对应的世界流会话
		//responseNewWorldAPITime := time.Now()
		if !conver_exist {
			//创建世界成功，保存相关信息到数据库
			// 创建一个世界会话的实例
			title := "id为" + utils.Strval(uid) + "的用户在" + worldName + "的世界中聊天"

			newWorldconversation.Uid = uid
			newWorldconversation.IsLiuId = response.ISLIUid
			newWorldconversation.WorldId = worldId
			newWorldconversation.WorldName = worldName
			newWorldconversation.Title = title
			newWorldconversation.BgInfo = BgInfo
			newWorldconversation.UserInfo = userInfo

			// 调用AddWorld函数添加新的世界
			err = models.AddWorldConversation(session, &newWorldconversation)
			if err != nil {
				fmt.Println("添加世界流会话失败:", err)
				return nil, nil, errors.New("添加世界流会话失败")
			}
			//return response, &newWorldconversation, nil
		} else {
			//如果已经存在世界流会话了，则更新意识流id
			wc.IsLiuId = response.ISLIUid
			newWorldconversation = *wc // 将已存在的会话对象赋值给newWorldconversation
			err := models.UpdateWorldConversation(session, wc)
			if err != nil {
				return nil, nil, errors.New("更新世界意识流id失败")
			}
		}
		// 计算整个函数执行的总时间

		//responseCode1Time2 := time.Since(responseNewWorldAPITime)
		//log.Printf(" 【 ==== 调用模型端创建世界接口,响应 response.Code = 1 后更新数据库 耗费时间: %s\n  ===】", responseCode1Time2.String())
		//c.JSON(http.StatusOK, gin.H{"code": 1, "message": "创建虚拟世界成功"})

	}

	//提交事务
	err = session.Commit()
	if err != nil {
		//ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "创建数字人失败! "})
		return nil, nil, nil
	}
	// 打印响应结果
	fmt.Println("world Response Code:", response.Code)
	fmt.Println("world ISLIUid:", response.ISLIUid)
	fmt.Println("world WObj:", response.WObj)

	fmt.Println("world ISLIU:", response.ISLIU)
	fmt.Println("world MessageStatusType:", response.MessageStatusType)

	return response, &newWorldconversation, nil

}

// ContainsString 检查字符串数组是否包含一个特定的字符串
func ContainsString(slice []string, item string) bool {
	for _, elem := range slice {
		if elem == item {
			return true
		}
	}
	return false
}
