package models

import (
	"WorldEpcho/src/config"
	"WorldEpcho/src/datasource"
	"errors"
	"fmt"
	"github.com/go-xorm/xorm"
	"log"
)

// DigitalPerson 表示数字人信息
type DigitalPerson struct {
	Id               int64  `json:"id"`
	Name             string `json:"name"`
	Gender           string `json:"gender"`
	Personality      string `json:"personality"`     //性格
	Catchphrases     string `json:"catchphrases"`    // 口头禅
	BackgroundInfo   string `json:"background_info"` // 使用string 处理可能为空的文本字段
	Visibility       string `json:"visibility"`
	MindDeep         int    `json:"IQ" xorm:"mind_deep"` //数字人聪明程度
	Author           int64  `json:"author"`
	InteractionCount int    `json:"interaction_count"`
}

var (
	NoDigitialPersonUpdate = errors.New("数字人信息未被更新")
)

// CreateDigitalPerson 创建数字人信息
/*
func CreateDigitalPerson(digitalPerson *DigitalPerson) error {
	affected, err := datasource.Engine.Insert(digitalPerson)
	if err != nil {
		log.Println(err.Error())
	}
	if affected == 0 {
		return errors.New("Failed to create digital person")
	}
	return nil
}
*/
func CreateDigitalPerson(digitalPerson *DigitalPerson, session *xorm.Session) error {

	affected, err := session.Insert(digitalPerson)
	if err != nil {
		log.Println(err.Error())
	}
	if affected == 0 {
		return errors.New("Failed to create digital person")
	}
	return nil
}

// GetDigitalPersonInfoByID 根据数字人ID 获取数字人的全部信息,包括资产信息
func GetDigitalPersonAllInfoByID(digitalId int64, session *xorm.Session) (*DigitalPersonInfo, error) {
	//digitalPerson := &DigitalPerson{Id: id}

	//定义查询结果的结构体
	var digitalPersonInfo struct {
		DigitalPerson `xorm:"extends"`
		SoulAsset     `xorm:"extends"`
	}
	// 联表查询
	has, err := session.Table("digital_person").
		Join("Left", "soul_asset", "digital_person.id=soul_asset.digital_id").
		Where("digital_person.id=?", digitalId).Get(&digitalPersonInfo)

	if err != nil {
		return nil, err
	}
	if !has {
		return nil, errors.New("根据数字人id数字人信息未查询到!")
	}
	//封装查询结果到DigitalPersonInfo结构体中
	digitalPersonInfoWrapper := &DigitalPersonInfo{
		DigitalPerson: &digitalPersonInfo.DigitalPerson,
		SoulAsset:     &digitalPersonInfo.SoulAsset,
	}

	return digitalPersonInfoWrapper, nil
}

// GetDigitalPersonByID 根据数字人ID 仅获取数字人信息,不包括数字人资产信息
func GetDigitalPersonByID(id int64) (*DigitalPerson, error) {
	digitalPerson := &DigitalPerson{Id: id}
	has, err := datasource.Engine.Get(digitalPerson)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, errors.New("Digital person not found")
	}
	return digitalPerson, nil
}

// UpdateDigitalPerson 更新数字人信息
func UpdateDigitalPerson(digitalPerson *DigitalPerson, session *xorm.Session) error {
	_, err := session.Id(digitalPerson.Id).Update(digitalPerson)
	if err != nil {
		return err
	}
	/*if affected == 0 {
		return NoDigitialPersonUpdate
	}*/
	return nil
}

// DeleteDigitalPersonByID 根据 Id 删除数字人信息
func DeleteDigitalPersonByID(id int64) error {
	affected, err := datasource.Engine.Id(id).Delete(&DigitalPerson{})
	if err != nil {
		return err
	}
	if affected == 0 {
		return errors.New("Failed to delete digital person")
	}
	return nil
}

// QueryDigitalPersons 根据数字人名称关键字模糊查询数字人信息
func QueryDigitalPersons1(userID int64, keyword string) ([]*DigitalPerson, error) {
	var digitalPeoples []*DigitalPerson
	var visibility = "public"
	//查询条件
	//err := datasource.Engine.Where("name LIKE ?", "%"+keyword+"%").And("visibility = ?", visibility).Find(&digitalPeoples)
	err := datasource.Engine.Where("name LIKE ? and author = ?  or visibility = ? ", "%"+keyword+"%", userID, visibility).Find(&digitalPeoples)
	if err != nil {
		return nil, err
	}
	return digitalPeoples, nil
}

/*
  用户表和数字人表联表查询,实现当前用户的id的用户等级为0时可以查询到所有数字人,
  如果当前的用户的等级不为0,只能查询到数字人名字模糊匹配到的,且用户id等于数字人创作者的,或者公开的数字人。
*/
func QueryDigitalPersons(userID int64, keyword string) ([]*DigitalPerson, error) {
	digitalPersons := make([]*DigitalPerson, 0)

	// 联表查询,连接用户表和数字人表,根据权限和关键词进行过滤
	err := datasource.Engine.Table("digital_person").Alias("dp").
		Join("INNER", "user", "user.id = ?", userID).
		Where("user.level = 0 OR (dp.author = ? AND dp.name LIKE ?) OR dp.visibility = 'public'",
			userID, "%"+keyword+"%").
		Find(&digitalPersons)
	if err != nil {
		return nil, err
	}
	fmt.Println(config.ColorBlue, "digitalPersons 模糊查询获取数字人个数:", len(digitalPersons), config.ColorReset)
	return digitalPersons, nil
}

// GetDigitalPersonInfo 函数,根据传入的 DigitalPerson 对象获取信息
func GetDigitalPersonInfo(digitalPerson *DigitalPerson) (*DigitalPerson, error) {
	// 根据 digitalPerson.Id 从数据库中获取信息
	has, err := datasource.Engine.ID(digitalPerson.Id).Get(digitalPerson)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, fmt.Errorf("未查询到数字人")
	}
	return digitalPerson, nil
}

// GetDigitalPersonInfo 函数,根据传入的 DigitalPerson 对象获取信息
func GetDigitalPersonInfoTrans(digitalPerson *DigitalPerson, session *xorm.Session) (*DigitalPerson, error) {
	// 根据 digitalPerson.Id 从数据库中获取信息
	has, err := session.ID(digitalPerson.Id).Get(digitalPerson)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, fmt.Errorf("未查询到数字人")
	}
	return digitalPerson, nil
}

// GetDigitalPeopleByUserID 根据用户Id获取所有数字人信息
func GetDigitalPeopleByUserID(userID int64) ([]DigitalPerson, error) {

	var digitalPeoples []DigitalPerson
	err := datasource.Engine.Where("author = ?", userID).Find(&digitalPeoples)
	if err != nil {
		return nil, err
	}
	return digitalPeoples, nil
}

// IncrementDigitalPersonInteractionCount 为指定ID的数字人增加交互量
func IncrementDigitalPersonInteractionCount(id int64) error {
	_, err := datasource.Engine.ID(id).Incr("interaction_count", 1).Update(&DigitalPerson{})
	return err
}

// GetDigitalPersonsByUserID 根据用户ID查询对应的数字人ID和名字
func GetDigitalPersonsByUserID(userID int64) ([]DigitalPerson, error) {
	var digitalPersons []DigitalPerson
	err := datasource.Engine.Table("digital_person").Join("INNER", "conversation", "digital_person.id = conversation.dp_id").
		Where("conversation.uid = ?", userID).
		//Select("digital_person.id, digital_person.name,digital_person.gender,catchphrases").
		Select("*").
		Find(&digitalPersons)
	if err != nil {
		return nil, err
	}
	return digitalPersons, nil
}