package models

import (
	"WorldEpcho/src/config"
	database "WorldEpcho/src/datasource"
	"encoding/json"
	"fmt"
	"github.com/go-xorm/xorm"
	"strings"
	"time"
)

//用户应用数据
type UserApplicationData struct {
	AppId      int64  `xorm:"'app_id'" json:"app_id"`                // 应用ID
	UserId     int64  `xorm:"'user_id'" json:"user_id"`              // 用户ID
	StatusData string `xorm:"'status_data' json" json:"status_data"` // 状态数据，以JSON格式存储
	CreatedAt  int64  `xorm:"created"`                               // 创建时间
	UpdatedAt  int64  `xorm:"updated"`                               // 更新时间
}

/*
   用户应用数据增删改查
*/
//创建用户应用数据
func CreateUserApplication(userAppData *UserApplicationData) error {
	_, err := database.Engine.Insert(userAppData)
	if err != nil {
		fmt.Println("创建用户应用数据失败!")
		errStr := err.Error()

		if strings.Contains(errStr, "Duplicate entry") {
			err := UpdateUserApplicationData(userAppData)
			if err != nil {
				return err
			}
			return nil
		}
		return err
	}
	return nil
}

//根据应用id, 查询用户应用数据
func GetUserApplicationData(appId, userId int64) (map[string]interface{}, error) {
	ua := UserApplicationData{AppId: appId, UserId: userId}
	_, err := database.Engine.Get(&ua)
	if err != nil {
		fmt.Println("查询用户应用数据失败!")
		return nil, err
	}
	var configData map[string]interface{}
	err = json.Unmarshal([]byte(ua.StatusData), &configData)
	if err != nil {
		return nil, fmt.Errorf("error unmarshaling config data: %w", err)
	}

	return configData, nil
}

// GetUserApplicationData 根据用户ID和应用ID查询用户应用数据的状态数据（StatusData）
func GetUserApplicationData_Tx(session *xorm.Session, appId, userId int64) (*UserApplicationData, error) {
	ua := UserApplicationData{AppId: appId, UserId: userId}
	// 通过指定的appId和userId尝试查找对应的用户应用数据
	found, err := session.Get(&ua)

	if err != nil {
		// 如果查询过程出错，返回错误信息
		return nil, fmt.Errorf("查询用户应用数据失败: %v", err)
	}

	if !found {
		// 如果没有找到对应的记录，返回一个适当的消息而不是一个空记录
		return nil, nil
	}

	// 如果一切正常, 返回查询到的结果
	return &ua, nil
}

//根据用户id获取用户应用数据
func GetUserApplicationDataByUserId(userId int64) (*UserApplicationData, error) {
	var data UserApplicationData

	// 使用 xorm 根据用户ID查询用户应用数据
	has, err := database.Engine.Where("user_id = ?", userId).Get(&data)
	if err != nil {
		return nil, err // 查询过程中出现错误
	}
	if !has {
		return nil, err // 没有找到相应的数据
	}

	return &data, nil // 返回查询到的用户应用数据
}

//更新用户应用数据
func UpdateUserApplicationData(ua *UserApplicationData) error {
	_, err := database.Engine.Where("app_id = ? and user_id = ?", ua.AppId, ua.UserId).Update(ua)
	if err != nil {
		fmt.Println("更新用户应用数据失败!")
		return err
	}
	return nil
}

//删除用户应用数据
func DeleteUserApplication(appID, userID int64) error {
	_, err := database.Engine.Where("app_id = ? and user_id = ?", appID, userID).Delete(&UserApplicationData{})
	if err != nil {
		fmt.Println("删除用户应用数据失败!")
		return err
	}
	return nil
}

//根据用户id和appId，以及用户权限，当用户的状态码为1时为展厅模式
func GetVisibleDigitalPersonsForUser(userId int64, appId int64) ([]DigitalPerson, error) {
	var digitalPersons []DigitalPerson
	var userAppData UserApplicationData
	// 只查询需要的字段
	has, err := database.Engine.Table("user_application_data").
		Where("user_id = ?", userId).And("app_id = ?", appId).Get(&userAppData)

	if err != nil {
		return nil, fmt.Errorf("获取用户应用数据出错: %v", err)
	}
	if !has {
		return nil, fmt.Errorf("根据用户和应用数据没匹配到相关应用数据")
	}

	var visibleIds []int64
	err = json.Unmarshal([]byte(userAppData.StatusData), &visibleIds)
	if err != nil {
		return nil, fmt.Errorf("解析状态数据出错: %v", err)
	}

	// Fetch the digital persons that are visible to this user based on status_data
	err = database.Engine.In("id", visibleIds).Find(&digitalPersons)
	if err != nil {
		return nil, fmt.Errorf("获取数字人数据出错: %v", err)
	}
	fmt.Println(config.ColorPurple, "展厅应用可见数字人id: ", visibleIds, config.ColorReset)
	fmt.Println(config.ColorBlue, "digitalPersons 模糊查询获取数字人个数：", len(digitalPersons), config.ColorReset)

	return digitalPersons, nil
}

// 根据用户 ID 和应用 ID 修改用户应用数据
func UpdateUserApplicationDataByUserIdAndAppId1(userId, appId int64, jsonData string) error {
	var userAppData UserApplicationData
	// 查询是否存在符合条件的记录
	exist, err := database.Engine.Where("user_id = ? AND app_id = ?", userId, appId).Get(&userAppData)
	if err != nil {
		return err
	}
	if !exist {
		// 未找到符合条件的记录
		return fmt.Errorf("未找到符合条件的记录")
	}

	// 更新 StatusData 字段
	userAppData.StatusData = jsonData

	// 执行更新操作
	_, err = database.Engine.Where("user_id = ? AND app_id = ?", userId, appId).Update(&userAppData)
	if err != nil {
		return err
	}

	return nil
}

// 根据用户 ID 和应用 ID 修改用户应用数据
func UpdateOrAddUserApplicationDataByUserIdAndAppId(userId, appId int64, jsonData string) error {
	var userAppData UserApplicationData
	// 查询是否存在符合条件的记录
	exist, err := database.Engine.Where("user_id = ? AND app_id = ?", userId, appId).Get(&userAppData)
	if err != nil {
		return err
	}
	if !exist {
		// 未找到符合条件的记录，则创建一条新的记录
		userAppData = UserApplicationData{
			UserId:     userId,
			AppId:      appId,
			StatusData: jsonData, // 假设 StatusData 是要更新的字段
			CreatedAt:  time.Now().Unix(),
			UpdatedAt:  time.Now().Unix(),
		}
		_, err = database.Engine.Insert(&userAppData)
		if err != nil {
			return err
		}
	} else {
		// 找到符合条件的记录，执行更新操作
		userAppData.StatusData = jsonData
		_, err = database.Engine.Where("user_id = ? AND app_id = ?", userId, appId).Update(&userAppData)
		if err != nil {
			return err
		}
	}

	return nil
}

// InsertOrUpdateStatusData 根据AppId和UserId插入或更新StatusData
func InsertOrUpdateStatusData(appId, userId int64, statusData string) error {

	userAppData := UserApplicationData{
		AppId:      appId,
		UserId:     userId,
		StatusData: statusData,
	}

	// 检查记录是否存在
	has, err := database.Engine.Where("app_id = ? AND user_id = ?", appId, userId).Exist(&UserApplicationData{})
	if err != nil {
		return err // 查询时出现错误
	}

	if has {
		// 记录存在，执行更新操作
		_, err = database.Engine.Where("app_id = ? AND user_id = ?", appId, userId).Cols("status_data").Update(&userAppData)
		if err != nil {
			return err // 更新时出现错误
		}
	} else {
		// 记录不存在，执行插入操作
		_, err = database.Engine.Insert(&userAppData)
		if err != nil {
			return err // 插入时出现错误
		}
	}

	return nil // 操作成功
}
