package groupPower_m

import (
	"context"
	"encoding/json"
	"fmt"
	"git.hilo.cn/hilo-common/domain"
	"git.hilo.cn/hilo-common/resource/mysql"
	"git.hilo.cn/hilo-common/resource/redisCli"
	"git.hilo.cn/hilo-common/utils"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"hilo-group/_const/enum/groupPower_e"
	"hilo-group/_const/redis_key"
	"hilo-group/domain/model/group_m"
	"hilo-group/myerr"
	"hilo-group/myerr/bizerr"
	"runtime/debug"
	"strconv"
	"time"
)

type GroupPower struct {
	mysql.Entity
	*domain.Model   `gorm:"-"`
	GroupUid        mysql.Str
	Name            mysql.Str
	Status          groupPower_e.GroupPowerStatus
	Nameplate       mysql.Str                    // 铭牌
	Declaration     mysql.Str                    // 宣言
	Icon            mysql.Str                    // 头像
	GradeName       mysql.Str                    // 等级称号
	GradeMedal      mysql.Str                    // 等级勋章图片
	Grade           groupPower_e.GroupPowerGrade `gorm:"-"`
	ModifyNameplate mysql.YesNo
}

type GroupPowerUser struct {
	mysql.Entity
	*domain.Model `gorm:"-"`
	GroupPowerId  mysql.ID
	UserId        mysql.ID
	Role          groupPower_e.GroupPowerUserRole
}

type ActFamilyMonthRankLog struct {
	Id         uint64 `json:"id"`
	Period     string `json:"period"`
	FamilyId   uint64 `json:"family_id"`
	RankFamily int    `json:"rank_family"`
	RankUser   int    `json:"rank_user"`
	UserId     uint64 `json:"user_id"`
	Award      string `json:"award"`
	Area       int    `json:"area"`
}

func (gpu *GroupPowerUser) Get(db *gorm.DB) ([]GroupPowerUser, error) {
	rows := make([]GroupPowerUser, 0)
	err := db.Where(gpu).Find(&rows).Error
	if err != nil {
		return nil, err
	}
	return rows, nil
}

func GetPowerOwner(db *gorm.DB, powerId uint64) (uint64, error) {
	gpu := GroupPowerUser{GroupPowerId: powerId, Role: groupPower_e.GroupPowerUserRoleMgr}
	records, err := gpu.Get(db)
	if err != nil {
		return 0, err
	}
	if len(records) != 1 {
		return 0, bizerr.GroupPowerNoOwner
	}
	return records[0].UserId, nil
}

func GetPowerOwnerMap(model *domain.Model, powerIds []uint64) (map[uint64]uint64, error) {
	rows := make([]GroupPowerUser, 0)
	if len(powerIds) > 0 {
		if err := model.DB().Model(&GroupPowerUser{}).
			Where("group_power_id IN ? and role = ?", powerIds, groupPower_e.GroupPowerUserRoleMgr).
			Find(&rows).Error; err != nil {
			return nil, err
		}
	}
	result := make(map[uint64]uint64, 0)
	for _, i := range rows {
		result[i.GroupPowerId] = i.UserId
	}
	return result, nil
}

func GetMyPowerId(db *gorm.DB, userId uint64) (uint64, error) {
	gpu := GroupPowerUser{UserId: userId, Role: groupPower_e.GroupPowerUserRoleMgr}
	records, err := gpu.Get(db)
	if err != nil {
		return 0, err
	}
	if len(records) > 0 {
		return records[0].GroupPowerId, nil
	}
	return 0, nil
}

func (gpu *GroupPowerUser) GetCount(db *gorm.DB) (uint, error) {
	var count int64 = 0
	err := db.Model(&GroupPowerUser{}).Where(gpu).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return uint(count), nil
}

type GroupPowerUserLog struct {
	mysql.Entity
	GroupPowerId mysql.ID
	UserId       mysql.ID
	OperateType  groupPower_e.GroupPowerUserLogType
	Remark       mysql.Str
}

//记录日志
func addGroupPowerUserLog(model *domain.Model, groupPowerId mysql.ID, userId mysql.ID, operateType groupPower_e.GroupPowerUserLogType, remark string) error {
	if err := model.Db.Create(&GroupPowerUserLog{
		GroupPowerId: groupPowerId,
		UserId:       userId,
		OperateType:  operateType,
		Remark:       remark,
	}).Error; err != nil {
		return myerr.WrapErr(err)
	}
	return nil
}

func GetGroupPowerUserLog(db *gorm.DB, groupPowerId mysql.ID, beginTime time.Time) ([]GroupPowerUserLog, error) {
	rows := make([]GroupPowerUserLog, 0)
	gpu := GroupPowerUserLog{GroupPowerId: groupPowerId}
	if err := db.Where(gpu).Where("created_time BETWEEN ? AND NOW()", beginTime).Order("id DESC").Find(&rows).Error; err != nil {
		return nil, err
	}
	return rows, nil
}

type GroupPowerDiamondLog struct {
	mysql.Entity
	GroupPowerId  mysql.ID
	SendUserId    mysql.ID
	SendGroupId   mysql.Str
	ReceiveUserId mysql.ID
	DiamondNum    mysql.Num
	GiftId        mysql.ID
	GiftNum       mysql.Num
	GiftOperateId mysql.ID
	Type          groupPower_e.GroupPowerDiamondLogType
}

func (*GroupPowerDiamondLog) TableName() string {
	month := time.Now().Format("200601")
	return fmt.Sprintf("group_power_diamond_log_%s", month)
}

func addGroupPowerDiamondLog(model *domain.Model, groupPowerId mysql.ID, sendUserId mysql.ID, sendGroupId mysql.Str, receiveUserId mysql.ID, diamondNum mysql.Num, giftId mysql.ID, giftNum mysql.Num, giftOperateId mysql.ID, t groupPower_e.GroupPowerDiamondLogType) error {
	if err := model.Db.Table((&GroupPowerDiamondLog{}).TableName()).Create(&GroupPowerDiamondLog{
		GroupPowerId:  groupPowerId,
		SendUserId:    sendUserId,
		SendGroupId:   sendGroupId,
		ReceiveUserId: receiveUserId,
		DiamondNum:    diamondNum,
		GiftId:        giftId,
		GiftNum:       giftNum,
		GiftOperateId: giftOperateId,
		Type:          t,
	}).Error; err != nil {
		return myerr.WrapErr(err)
	}

	go func() {
		defer func() {
			if r := recover(); r != nil {
				//打印错误堆栈信息
				model.Log.Errorf("GroupPowerDiamondLog Persistent SYSTEM ACTION PANIC: %v, stack: %v", r, string(debug.Stack()))
			}
		}()
		//增加到缓存,不要处理错误,接受缓存失败
		now := time.Now()
		nowTime, err := time.ParseInLocation(utils.DATE_FORMAT, now.Format(utils.DATE_FORMAT), time.Local)
		if err != nil {
			model.Log.Infof("addGroupPowerDiamondLog ZIncrBy err:%v", err)
		}
		beginDate := utils.GetMonday(nowTime)
		key := redis_key.GetGroupPowerDiamondLogWeek(beginDate.Format(utils.COMPACT_DATE_FORMAT))
		if err := redisCli.GetRedis().ZIncrBy(context.Background(), key, float64(diamondNum), strconv.FormatUint(groupPowerId, 10)).Err(); err != nil {
			model.Log.Infof("addGroupPowerDiamondLog ZIncrBy err:%v", err)
		}
		if ttl, err := redisCli.GetRedis().TTL(context.Background(), key).Result(); err != nil {
			model.Log.Errorf("addGroupPowerDiamondLog ZIncrBy TTL err:%v, key:%v", err, key)
		} else {
			if ttl < 0 {
				//延长到30天,避免数据丢失
				redisCli.GetRedis().ExpireAt(context.Background(), key, time.Now().AddDate(0, 0, 30))
			}
		}
	}()
	return nil
}

type GroupPowerWeekDiamond struct {
	Week    string
	PowerId mysql.ID
	GroupId mysql.Str
	Diamond uint64
}

func (gpwd *GroupPowerWeekDiamond) AddDiamond(db *gorm.DB) error {
	return db.Clauses(clause.OnConflict{
		DoUpdates: clause.Assignments(map[string]interface{}{
			"diamond": gorm.Expr("diamond + ?", gpwd.Diamond)}),
	}).Create(gpwd).Error
}

func GetPowerWeekDiamond(db *gorm.DB, week string, powerId mysql.ID) (uint32, error) {
	gpwd := GroupPowerWeekDiamond{Week: week, PowerId: powerId}
	type summary struct {
		Sum uint32
	}
	row := summary{}

	if err := db.Model(&GroupPowerWeekDiamond{}).
		Select("SUM(diamond) AS sum").Where(&gpwd).First(&row).Error; err != nil {
		return 0, err
	}
	return row.Sum, nil
}

func GetAllPowerWeekDiamond(db *gorm.DB, week string) (map[uint64]uint32, error) {
	gpwd := GroupPowerWeekDiamond{Week: week}
	type summary struct {
		PowerId uint64
		Sum     uint32
	}
	rows := make([]summary, 0)

	if err := db.Model(&GroupPowerWeekDiamond{}).
		Select("power_id, SUM(diamond) AS sum").Where(&gpwd).Group("power_id").Find(&rows).Error; err != nil {
		return nil, err
	}

	result := make(map[uint64]uint32, 0)
	for _, i := range rows {
		result[i.PowerId] = i.Sum
	}
	return result, nil
}

type PowerSupportAward struct {
	mysql.Entity
	Week             string
	PowerId          mysql.ID
	Diamond          uint32
	Level            string
	Owner            mysql.ID
	OwnerSalary      uint32
	Assistant_1      mysql.ID
	Assistant_2      mysql.ID
	Assistant_3      mysql.ID
	Assistant_Salary uint32
}

func (psa *PowerSupportAward) Create(db *gorm.DB) (int64, error) {
	result := db.Clauses(clause.OnConflict{DoNothing: true}).
		Create(psa)
	return result.RowsAffected, result.Error
}

func (psa *PowerSupportAward) Find(db *gorm.DB) (*PowerSupportAward, error) {
	rows := make([]PowerSupportAward, 0)
	if err := db.Where(psa).Find(&rows).Error; err != nil {
		return nil, err
	}
	if len(rows) <= 0 {
		return nil, nil
	}
	return &rows[0], nil
}

func (psa *PowerSupportAward) FindAll(db *gorm.DB) ([]PowerSupportAward, error) {
	rows := make([]PowerSupportAward, 0)
	if err := db.Where(psa).Find(&rows).Error; err != nil {
		return nil, err
	}
	return rows, nil
}

func GetGroupPowerByUserId(model *domain.Model, userId uint64) (*GroupPower, error) {
	if groupPowerUser, err := GetGroupPowerUserOrNil(model, userId); err != nil {
		return nil, err
	} else if groupPowerUser == nil {
		return nil, nil
	} else {
		return GetGroupPowerOrErr(model, groupPowerUser.GroupPowerId)
	}
}

func GetGroupPowerOrErr(model *domain.Model, id uint64) (*GroupPower, error) {
	groupPower := GroupPower{}
	if err := model.Db.Model(&GroupPower{}).First(&groupPower, id).Error; err != nil {
		return nil, myerr.WrapErr(err)
	}
	groupPower.Model = model
	return &groupPower, nil
}

func InitGroupPower(model *domain.Model, groupUuid string, name string, owerUserId mysql.ID) (*GroupPower, *GroupPowerUser, error) {
	//检查改用户是否已经加入了别的势力
	/*	var n int64
		if err := model.Db.Model(&GroupPowerUser{}).Where(&GroupPowerUser{
			UserId: owerUserId,
		}).Count(&n).Error; err != nil {
			return nil, nil, myerr.NewSysErrorF("用户已经加入了别的势力")
		}*/
	if flag, _, err := CheckGroupPowerUser(model, owerUserId); err != nil {
		return nil, nil, err
	} else if flag {
		return nil, nil, myerr.NewSysErrorF("用户已经加入了别的势力")
	}
	return &GroupPower{
			Model:    model,
			GroupUid: groupUuid,
			Name:     name,
			Status:   groupPower_e.GroupPowerUserHas,
		}, &GroupPowerUser{
			Model:        model,
			GroupPowerId: 0,
			UserId:       owerUserId,
			Role:         groupPower_e.GroupPowerUserRoleMgr,
		}, nil
}

//获取用户所在的国家势力信息,不存在则为nil
func GetGroupPowerUserOrNil(model *domain.Model, userId mysql.ID) (*GroupPowerUser, error) {
	groupPowerUser := GroupPowerUser{}
	if err := model.Db.Where(&GroupPowerUser{
		UserId: userId,
	}).First(&groupPowerUser).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		} else {
			return nil, myerr.WrapErr(err)
		}
	}
	groupPowerUser.Model = model
	return &groupPowerUser, nil
}

func GetGroupPowerByGroupOrNil(model *domain.Model, groupUid string) (*GroupPower, error) {
	groupPower := GroupPower{}
	if err := model.Db.Where(&GroupPower{
		GroupUid: groupUid,
	}).First(&groupPower).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		} else {
			return nil, myerr.WrapErr(err)
		}
	}
	groupPower.Model = model
	return &groupPower, nil
}

// 某个势力的势力主是否是代理
func IsGroupPowerHasMgrDealer(model *domain.Model, groupId mysql.ID) (bool, error) {
	var num int64
	if err := model.Db.Raw("select count(1) from (select * from diamond_dealer where user_id in "+
		"(select user_id from group_power_user where group_power_id = ? and role = ?)) a", groupId, groupPower_e.GroupPowerUserRoleMgr).
		Scan(&num).Error; err != nil {
		return false, myerr.WrapErr(err)
	}
	if num > 0 {
		return true, nil
	}
	return false, nil
}

// 某个家族是否有家族代理
func IsGroupPowerHasFamilyAgent(model *domain.Model, groupId mysql.ID) (bool, error) {
	var num int64
	if err := model.Db.Raw("select count(1) from diamond_dealer where status=1 and is_family_agent=1 and user_id in "+
		"(select user_id from group_power_user where group_power_id = ?)", groupId).
		Scan(&num).Error; err != nil {
		return false, myerr.WrapErr(err)
	}
	if num > 0 {
		return true, nil
	}
	return false, nil
}

func GetGroupPowerMap(db *gorm.DB, userIds []mysql.ID) (map[mysql.ID]uint64, error) {
	rows := make([]GroupPowerUser, 0)
	if len(userIds) > 0 {
		if err := db.Model(&GroupPowerUser{}).Where("user_id IN ?", userIds).Find(&rows).Error; err != nil {
			return nil, err
		}
	}
	result := make(map[mysql.ID]uint64, 0)
	for _, i := range rows {
		result[i.UserId] = i.GroupPowerId
	}
	return result, nil
}

// return
func GetGroupPowerNames(db *gorm.DB, ids []mysql.ID) (map[mysql.ID]string, map[mysql.ID]string, error) {
	type record struct {
		Id        mysql.ID
		Name      string
		Nameplate string
	}
	rows := make([]record, 0)
	result := make(map[mysql.ID]string, 0)
	result2 := make(map[mysql.ID]string, 0)
	if len(ids) > 0 {
		if err := db.Model(&GroupPower{}).Select("p.id, i.name,p.nameplate").
			Joins("AS p INNER JOIN group_info AS i ON p.group_uid = i.im_group_id").
			Where("p.id IN ?", ids).Find(&rows).Error; err != nil {
			return result, result2, err
		}
	}
	for _, i := range rows {
		result[i.Id] = i.Name
		result2[i.Id] = i.Nameplate
	}
	return result, result2, nil
}

func GetGroupPower(model *domain.Model, id mysql.ID) (*GroupPower, error) {
	groupPower := GroupPower{}
	if err := model.Db.Model(&GroupPower{}).First(&groupPower, id).Error; err != nil {
		return nil, myerr.WrapErr(err)
	}
	groupPower.Model = model
	return &groupPower, nil
}

// 判断势力是否合法
func IsGroupPowerActive(model *domain.Model, id mysql.ID) (bool, error) {
	gp, err := GetGroupPower(model, id)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return false, nil
		} else {
			return false, err
		}
	}
	if gp == nil || gp.Status != groupPower_e.GroupPowerUserHas {
		return false, nil
	}
	return true, nil
}

func getGroupPowerUser(model *domain.Model, groupPowerId mysql.ID, userId mysql.ID) (*GroupPowerUser, error) {
	groupPowerUser := GroupPowerUser{}
	if err := model.Db.Where(&GroupPowerUser{
		GroupPowerId: groupPowerId,
		UserId:       userId,
	}).First(&groupPowerUser).Error; err != nil {
		return nil, myerr.WrapErr(err)
	}
	groupPowerUser.Model = model
	return &groupPowerUser, nil
}

//false:不存在, true:存在
func CheckGroupPowerUser(model *domain.Model, userId mysql.ID) (bool, mysql.ID, error) {
	groupPowerUser := GroupPowerUser{}
	if err := model.Db.Where(&GroupPowerUser{
		UserId: userId,
	}).First(&groupPowerUser).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return false, 0, nil
		} else {
			return false, 0, myerr.WrapErr(err)
		}
	}
	return true, groupPowerUser.GroupPowerId, nil
}

//获取势力主
func GetGroupPowerMgr(model *domain.Model, groupPowerId mysql.ID) (mysql.ID, error) {
	groupPowerUser := GroupPowerUser{}
	if err := model.Db.Where(&GroupPowerUser{
		GroupPowerId: groupPowerId,
		Role:         groupPower_e.GroupPowerUserRoleMgr,
	}).First(&groupPowerUser).Error; err != nil {
		return 0, myerr.WrapErr(err)
	}
	return groupPowerUser.UserId, nil
}

//获取势力主和管理员
func GetGroupPowerMgrList(model *domain.Model, groupPowerId mysql.ID) ([]mysql.ID, error) {
	res := make([]mysql.ID, 0)
	err := model.Db.Model(GroupPowerUser{}).Select("user_id").Where("group_power_id = ? and role in (2,3)", groupPowerId).Scan(&res).Error
	if err != nil {
		return res, myerr.WrapErr(err)
	}
	return res, nil
}

//运营平台让用户离开
func (groupPower *GroupPower) MgrUserLeave(userId mysql.ID) (*GroupPowerUser, error) {
	//
	groupPowerUser, err := getGroupPowerUser(groupPower.Model, groupPower.ID, userId)
	if err != nil {
		return nil, err
	}
	if groupPowerUser.Role == groupPower_e.GroupPowerUserRoleMgr {
		return nil, bizerr.GroupPowerOwnerLeave
	}

	if err := addGroupPowerUserLog(groupPower.Model, groupPower.ID, userId, groupPower_e.GroupPowerUserLogTypeMgrLeave, ""); err != nil {
		return nil, err
	}
	groupPowerUser.SetDel()
	return groupPowerUser, nil
}

//正常
func (groupPower *GroupPower) MgrNormal() *GroupPower {
	groupPower.Status = groupPower_e.GroupPowerUserHas
	return groupPower
}

//冻结
func (groupPower *GroupPower) MgrFrozen() *GroupPower {
	groupPower.Status = groupPower_e.GroupPowerUserNo
	return groupPower
}

//解散。移除所有信息
func (groupPower *GroupPower) MgrDissolve() (*GroupPower, error) {
	//对比查询的数量 == 删除的数量,不一致,则不能删除
	if groupPower.ID == 0 {
		return groupPower, myerr.NewSysErrorF("groupPower dissolve groupPowerId = 0")
	}

	groupPowerUsers := []GroupPowerUser{}
	if err := groupPower.Db.Model(&GroupPowerUser{}).Where(&GroupPowerUser{
		GroupPowerId: groupPower.ID,
	}).Find(&groupPowerUsers).Error; err != nil {
		return nil, myerr.WrapErr(err)
	}
	if len(groupPowerUsers) == 0 {
		return nil, myerr.NewSysErrorF("groupPower dissolve user.num == 0")
	}

	//删除groupPowerUser中信息
	delN := groupPower.Db.Model(&GroupPowerUser{}).Where(&GroupPowerUser{
		GroupPowerId: groupPower.ID,
	}).Delete(&GroupPowerUser{
		GroupPowerId: groupPower.ID,
	}).RowsAffected
	if int64(len(groupPowerUsers)) != delN {
		return nil, myerr.NewSysErrorF("groupPower dissolve delN != selectN")
	}
	groupPowerUserStr, err := json.Marshal(groupPowerUsers)
	if err != nil {
		return nil, myerr.WrapErr(err)
	}

	//增加删除日志
	if err := addGroupPowerUserLog(groupPower.Model, groupPower.ID, 0, groupPower_e.GroupPowerUserLogDissolve, string(groupPowerUserStr)); err != nil {
		return nil, myerr.WrapErr(err)
	}
	//
	groupPower.Status = groupPower_e.GroupPowerDissolve
	groupPower.GroupUid = groupPower.GroupUid + "_" + "del" + "_" + time.Now().Format(utils.COMPACT_MONTH_FORMAT)
	return groupPower, nil
}

//修改名字
func (groupPower *GroupPower) EditName(name string) *GroupPower {
	groupPower.Name = name
	return groupPower
}

//修改群组
func (groupPower *GroupPower) EditGroupUid(groupUid string) *GroupPower {
	groupPower.GroupUid = groupUid
	return groupPower
}

func (groupPower *GroupPower) EditPowerOwer(owerUserId mysql.ID) (*GroupPower, *GroupPowerUser, *GroupPowerUser, error) {
	oldGroupPowerUser := GroupPowerUser{}
	if err := groupPower.Db.Where(&GroupPowerUser{
		GroupPowerId: groupPower.ID,
		Role:         groupPower_e.GroupPowerUserRoleMgr,
	}).First(&oldGroupPowerUser).Error; err != nil {
		return nil, nil, nil, myerr.WrapErr(err)
	}
	//势力主离开,
	if oldGroupPowerUser.UserId == owerUserId {
		//势力主没有变化,无需修改
		return groupPower, nil, nil, nil
	} else {
		oldGroupPowerUser.Model = groupPower.Model
		oldGroupPowerUser.SetDel()
		if err := addGroupPowerUserLog(groupPower.Model, groupPower.ID, oldGroupPowerUser.UserId, groupPower_e.GroupPowerUserLogTypeMgrLeave, ""); err != nil {
			return nil, nil, nil, err
		}
	}
	//
	return groupPower, &oldGroupPowerUser, &GroupPowerUser{
		Model:        groupPower.Model,
		GroupPowerId: groupPower.ID,
		UserId:       owerUserId,
		Role:         groupPower_e.GroupPowerUserRoleMgr,
	}, nil
}

//增加普通用户
func (groupPower *GroupPower) UserJoin(userId mysql.ID) (*GroupPowerUser, error) {
	//判断是否已经加入了国家势力
	if flag, groupPowerId, err := CheckGroupPowerUser(groupPower.Model, userId); err != nil {
		return nil, err
	} else if flag == true {
		if groupPowerId == groupPower.ID {
			return nil, bizerr.GroupPowerHasJoinMy
		} else {
			return nil, bizerr.GroupPowerHasJoinOther
		}
	}
	if err := addGroupPowerUserLog(groupPower.Model, groupPower.ID, userId, groupPower_e.GroupPowerUserLogTypeUserJoin, ""); err != nil {
		return nil, err
	}
	return &GroupPowerUser{
		Model:        groupPower.Model,
		GroupPowerId: groupPower.ID,
		UserId:       userId,
		Role:         groupPower_e.GroupPowerUserRoleUser,
	}, nil
}

// 离开国家势前至少要多少小时
const GROUP_POWER_LEAVE_LIMIT = 3

//用户退出国家势力
func (groupPower *GroupPower) UserLeave(userId mysql.ID) (*GroupPowerUser, time.Duration, error) {
	groupPowerUser, err := getGroupPowerUser(groupPower.Model, groupPower.ID, userId)
	if err != nil {
		return nil, 0, err
	}
	if groupPowerUser.Role == groupPower_e.GroupPowerUserRoleMgr {
		return nil, 0, bizerr.GroupPowerOwnerLeave
	}
	// 2022-02-14产品增加限制:加入势力10天内不能退出;2022-02-28:调整为15天;2022-06-20调整为3小时
	now := time.Now()
	endTime := groupPowerUser.CreatedTime.Add(time.Hour * GROUP_POWER_LEAVE_LIMIT)
	if now.Before(endTime) {
		diff := endTime.Sub(now)
		return nil, diff, bizerr.GroupPowerStayTooShort
	}

	if err := addGroupPowerUserLog(groupPower.Model, groupPower.ID, userId, groupPower_e.GroupPowerUserLogTypeUserLeave, ""); err != nil {
		return nil, 0, err
	}
	groupPowerUser.SetDel()
	return groupPowerUser, 0, nil
}

// 查询用户加入的国家势力ID及名称(势力绑定的群组的名称)
func GetUserGroupPower(model *domain.Model, userId uint64) (uint64, string, error) {
	gpu, err := GetGroupPowerUserOrNil(model, userId)
	if err != nil {
		return 0, "", err
	}
	if gpu == nil || gpu.GroupPowerId == 0 {
		return 0, "", nil
	}
	gp, err := GetGroupPowerOrErr(model, gpu.GroupPowerId)
	if err != nil {
		return 0, "", err
	}

	powerName := ""
	if gp != nil && len(gp.GroupUid) > 0 {
		gi, err := group_m.GetGroupInfo(model, gp.GroupUid)
		if err != nil {
			return 0, "", err
		}
		if gi != nil {
			// 只要前15个字
			s := []rune(gi.Name)
			if len(s) <= 15 {
				powerName = string(s)
			} else {
				powerName = string(s[0:15])
			}
		}
	}
	return gpu.GroupPowerId, powerName, nil
}

// 获取势力下的所有群组
func GetGroupPowerGroups(model *domain.Model, groupPowerId mysql.ID) ([]*group_m.GroupInfo, error) {
	var res []*group_m.GroupInfo
	var ownerIds []mysql.ID
	if err := model.DB().Model(GroupPowerUser{}).Select("user_id").Where("group_power_id = ?", groupPowerId).Scan(&ownerIds).Error; err != nil {
		model.Log.Errorf("GetGroupPowerGroups fail:%v", err)
		return nil, err
	}
	if len(ownerIds) <= 0 {
		return res, nil
	}
	if err := model.DB().Model(group_m.GroupInfo{}).Where("owner in ?", ownerIds).Find(&res).Error; err != nil {
		model.Log.Errorf("GetGroupPowerGroups fail:%v", err)
		return nil, err
	}
	return res, nil
}

// 批量获取势力用户
// return userId->GroupPowerUser
func BatchGetGroupPowerUser(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]GroupPowerUser, error) {
	var rows []GroupPowerUser
	res := make(map[mysql.ID]GroupPowerUser)
	if err := model.Db.Model(GroupPowerUser{}).Where("user_id in ?", userIds).Find(&rows).Error; err != nil {
		model.Log.Errorf("BatchGetGroupPowerUser fail:%v", err)
		return res, err
	}
	for i, v := range rows {
		res[v.UserId] = rows[i]
	}
	return res, nil
}

func CreateActFamilyMonthRankLog(model *domain.Model, list []*ActFamilyMonthRankLog) error {
	return model.DB().CreateInBatches(&list, 50).Error
}