package controllers

import (
	"WorldEpcho/src/config"
	"WorldEpcho/src/config/e"
	database "WorldEpcho/src/datasource"
	"WorldEpcho/src/models"
	"WorldEpcho/src/service"
	"WorldEpcho/src/utils"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"strings"
	"time"
)

// 定义英文-中文对照字典
/*var NpcRoleDetail = map[string]string{
	"roleName":                "角色名称",
	"introduction":            "简介",
	"consumptionExpectations": "消费心理预期",
	"psychologicalTraits":     "心理特征",
	"appearance":              "外观",
	"personality":             "性格",
	"decisionMakingStyle":     "决策风格",
	"riskPreference":          "风险偏好",
	"attitudeTowardsUsers":    "对用户的态度",
	"educationLevel":          "教育水平",
	"professionalBackground":  "职业背景",
	"purpose":                 "目的性",
	"knownInformation":        "已知信息",
}
*/
//创建角色画像的请求体
type NpcRoleRequest struct {
	Name              string         `json:"name"`             // 名称
	Details           models.Details `json:"details"`          //详情
	Gender            string         `json:"gender"`           //性别
	Tags              string         `json:"tags"`             //世界标签集
	RelatedWorlds     string         `json:"relatedWorlds"`    //相关世界
	UpdateTime        int64          `json:"updateTime"`       //更新时间
	CreateTime        int64          `json:"createTime"`       //构造时间
	ServiceProviderId string         `json:"authId,omitempty"` // ServiceProviderId

}

//创建Npc用户画像的接口
func CreateNpcUserPortrait(ctx *gin.Context) {

	var NpcRequest NpcRoleRequest
	if err := ctx.ShouldBindJSON(&NpcRequest); err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": e.InvalidParams, "data": nil, "message": "请求数据不正确"})
		return
	}
	// 从请求头 Authorization 中提取令牌
	tokenString := ctx.GetHeader("Token")
	if tokenString != "" {
		// 解析并验证 JWT 令牌
		isValid, err := service.IsValidMiGuToken(tokenString)
		if err != nil || !isValid {
			ctx.JSON(http.StatusOK, gin.H{"code": e.InvalidToken, "data": nil, "message": "无效或已过期的令牌"})
			return
		}
	} else {
		ctx.JSON(http.StatusOK, gin.H{"code": e.UnauthorizedStatus, "data": nil, "message": "请求头中无token,或未授权的token访问"})
		return
	}

	if NpcRequest.Name == "" {
		ctx.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "用户角色名称不能为空"})
		return
	}

	if NpcRequest.ServiceProviderId == "" {
		ctx.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "服务商id不能为空"})
		return
	}

	sp, err := models.GetServiceProviderById(NpcRequest.ServiceProviderId)
	if err != nil || sp == nil {
		ctx.JSON(http.StatusOK, gin.H{"code": e.NotFound, "data": nil, "message": "根据服务商id查询服务商出错或服务商不存在", "error": err.Error()})
		return
	}
	//可以访问的标签
	// 创建一个空切片存储匹配的标签
	matchingTags := []string{}

	// 分割字符串，得到单独的字符串
	tagsSplit := strings.Split(NpcRequest.Tags, ",")
	for _, tagStr := range tagsSplit {

		//如果包含服务商可访问的世界标签，则遍历将包含的标签放入数组
		// 检查每个用户标签是否被服务商允许
		if ContainsString(sp.AccessibleTags, tagStr) {
			matchingTags = append(matchingTags, tagStr)
		}

	}
	// 如果没有任何匹配的标签，则返回错误信息
	if len(matchingTags) == 0 {
		ctx.JSON(http.StatusOK, gin.H{"code": e.NotFound, "data": nil, "message": "不包含该服务商可访问的世界标签!"})
		fmt.Println("不包含该服务商可访问的世界标签")
		return
	}

	// 序列化 Details 为 JSON 字符串
	detailsJSON, err := json.Marshal(NpcRequest.Details)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": e.InternalError, "data": nil, "message": "详情信息序列化失败"})
		return
	}

	if string(detailsJSON) == "" {
		ctx.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "用户详情信息不能为空"})
		return
	}

	/* configData 英文键转换为中文 */

	var data map[string]interface{}
	if err := json.Unmarshal([]byte(string(detailsJSON)), &data); err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": e.ParamParseError, "data": nil, "message": "解析用户画像详细信息数据出错"})
		return
	}
	// 转换键名 => 英文转中文
	NpcRoleDetailTranslations := config.Conf.NpcRoleDetailTranslations
	translatedData := utils.TranslateKeysEnglishToChinese(NpcRoleDetailTranslations, data)

	translatedJSON, err := json.MarshalIndent(translatedData, "", "    ")
	if err != nil {
		fmt.Println("Error marshalling JSON:", err)
		ctx.JSON(http.StatusOK, gin.H{"code": e.ParamParseError, "data": nil, "message": "解析用户画像详细信息数据出错"})
		return
	}
	fmt.Println(" Details  translatedJSON ==> ", string(translatedJSON))

	// 创建一个空切片存储相关世界
	relatedWorldIds := []int64{}
	// 分割字符串，得到单独的字符串
	RelatedWorldIdsSplit := strings.Split(NpcRequest.RelatedWorlds, ",")
	for _, RelatedWorldId := range RelatedWorldIdsSplit {
		worldId, err := strconv.ParseInt(RelatedWorldId, 10, 64)
		if err != nil {
			ctx.JSON(http.StatusOK, gin.H{"code": e.ParamParseError, "data": nil, "message": "相关世界ID类型转换错误"})
			return
		}
		relatedWorldIds = append(relatedWorldIds, worldId)
	}
	//开启事务
	session := database.Engine.NewSession()
	defer session.Close()
	if err := session.Begin(); err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": e.InternalError, "data": nil, "message": "开启事务失败"})
		return
	}

	//用户画像详情信息
	/*
		// 将Details结构体转换为 JSON
			jsonData, err := json.Marshal(NpcRequest.Details)
			if err != nil {
				fmt.Println("Error:", err)
				return
			}
	*/

	npcUserRole := &models.NpcRole{
		Name:          NpcRequest.Name,
		Details:       string(translatedJSON),
		Gender:        NpcRequest.Gender,
		Tags:          matchingTags,
		RelatedWorlds: relatedWorldIds,
		CreateTime:    time.Now().Unix(),
		UpdateTime:    time.Now().Unix(),
	}

	var newNpcRole *models.NpcRole
	if newNpcRole, err = models.CreateNpcRole(session, npcUserRole); err != nil {
		session.Rollback()
		ctx.JSON(http.StatusOK, gin.H{"code": e.ErrorDatabase, "data": nil, "message": "创建用户画像信息出错"})
		return
	}

	if err := session.Commit(); err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": e.InternalError, "data": nil, "message": "事务提交失败"})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{"code": e.SUCCESS, "data": gin.H{"newNpcRoleInfo": newNpcRole}, "message": "创建用户画像成功"})

}

// 定义查询业务经理考核系统世界信息的请求参数的结构体
type NpcRoleRequestParams struct {
	WorldId           int64  `json:"worldId"`
	Tags              string `json:"tags"`
	ServiceProviderId string `json:"authId,omitempty"` // ServiceProviderId
}

// 查询业务经理考核相关的世界信息接口2
func QueryNpcRoleInfo(ctx *gin.Context) {
	var params NpcRoleRequestParams

	// 从请求体解析 JSON 参数
	if err := ctx.BindJSON(&params); err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": e.ParamParseError, "data": nil, "message": "参数解析错误"})
		return
	}

	// 从请求头 Authorization 中提取令牌
	tokenString := ctx.GetHeader("Token")
	if tokenString == "" {
		ctx.JSON(http.StatusOK, gin.H{"code": e.UnauthorizedStatus, "data": nil, "message": "请求头中无token,或未授权的token访问"})
		return
	}

	// 解析并验证 JWT 令牌
	isValid, err := service.IsValidMiGuToken(tokenString)
	if err != nil || !isValid {
		ctx.JSON(http.StatusOK, gin.H{"code": e.InvalidToken, "data": nil, "message": "无效或已过期的令牌"})
		return
	}

	if params.ServiceProviderId == "" {
		ctx.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "服务商id不能为空"})
		return
	}

	sp, err := models.GetServiceProviderById(params.ServiceProviderId)
	if err != nil || sp == nil {
		ctx.JSON(http.StatusOK, gin.H{"code": e.NotFound, "data": nil, "message": "根据服务商id查询服务商出错或服务商不存在", "error": err.Error()})
		return
	}
	//可以访问的标签
	// 创建一个空切片存储匹配的标签
	matchingTags := []string{}

	// 分割字符串，得到单独的字符串
	tagsSplit := strings.Split(params.Tags, ",")
	for _, tagStr := range tagsSplit {

		//如果包含服务商可访问的世界标签，则遍历将包含的标签放入数组
		// 检查每个用户标签是否被服务商允许
		if ContainsString(sp.AccessibleTags, tagStr) {
			matchingTags = append(matchingTags, tagStr)
		}
	}

	// 如果没有任何匹配的标签，则返回错误信息
	if len(matchingTags) == 0 {
		ctx.JSON(http.StatusOK, gin.H{"code": e.NotFound, "data": nil, "message": "不包含该服务商可访问的世界标签!"})
		fmt.Println("不包含该服务商可访问的世界标签")
		return
	}

	/*
		worldInfo, err := models.FindWorlds2(params.WorldName, tagsArr)
		if err != nil {
			ctx.JSON(http.StatusOK, gin.H{"code": e.ErrorDatabase, "data": nil, "message": "查询世界信息失败"})
			return
		}*/
	//开启事务
	session := database.Engine.NewSession()
	defer session.Close() //延迟关闭session
	err1 := session.Begin()
	if err1 != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "开启事务失败!"})
		fmt.Println("开启事务失败")
		return
	}
	//查询包含指定related_worlds ID的NPC角色数组
	npcRoles, err := models.FindNpcRolesByWorldID(session, params.WorldId)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": e.ErrorDatabase, "data": nil, "message": "根据相关世界ID查询用户画像信息出错!"})
		fmt.Println("根据相关世界ID查询用户画像信息出错")
		return
	}
	/*
	  转换世界配置信息中的英文字段
	*/
	var data map[string]interface{}

	for i, npcRole := range npcRoles {
		if err := json.Unmarshal([]byte(npcRole.Details), &data); err != nil {
			ctx.JSON(http.StatusOK, gin.H{"code": e.ParamParseError, "data": nil, "message": "解析用户画像详情信息数据出错"})
			return
		}
		// 转换键名
		// 中文转英文
		ReverseTranslations := config.Conf.NpcRoleDetailReverseTranslations
		translatedData := utils.TranslateKeysChineseToEnglish(ReverseTranslations, data)
		translatedJSON, err := json.MarshalIndent(translatedData, "", "    ")
		if err != nil {
			fmt.Println("Error marshalling JSON:", err)
			ctx.JSON(http.StatusOK, gin.H{"code": e.ParamParseError, "data": nil, "message": "解析用户画像详情信息数据出错"})
			return
		}
		npcRoles[i].Details = string(translatedJSON)
		fmt.Println(" configData translatedJSON ==> ", string(translatedJSON))
	}

	//提交事务
	err = session.Commit()
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "提交事务失败"})
		return
	}
	if npcRoles != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code":    e.SUCCESS,
			"data":    gin.H{"npcRoles": npcRoles},
			"message": "查询相关世界的用户画像信息成功",
		})
	} else {
		ctx.JSON(http.StatusOK, gin.H{
			"code":    e.NotFound,
			"data":    nil,
			"message": "未查相关世界的用户画像信息",
		})
	}
}
