package group_power_r

import (
	"fmt"
	"git.hilo.cn/hilo-common/domain"
	"git.hilo.cn/hilo-common/mycontext"
	"git.hilo.cn/hilo-common/resource/mysql"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/now"
	"hilo-group/_const/enum/groupPower_e"
	"hilo-group/_const/enum/msg_e"
	"hilo-group/_const/redis_key/groupPower_k"
	"hilo-group/cv/group_power_cv"
	"hilo-group/domain/model/groupPower_m"
	"hilo-group/domain/model/msg_m"
	"hilo-group/domain/model/user_m"
	"hilo-group/domain/service/group_power_s"
	"hilo-group/myerr/bizerr"
	"hilo-group/resp"
	"time"
)

type MGetGroupPowerReq struct {
	Ids []mysql.ID `form:"ids" binding:"required"`
}

// @Tags 国家势力-内部
// @Summary 批量获取国家势力信息
// @Param ids query string true "用户id,如:ids=1&ids=2&ids=3"
// @Success 200 {object} map[mysql.ID]group_power_cv.CvGroupPowerInfo
// @Router /inner/groupPower/infos [get]
func MGetGroupPowers(c *gin.Context) (*mycontext.MyContext, error) {
	myCtx := mycontext.CreateMyContext(c.Keys)
	var model = domain.CreateModelContext(myCtx)
	var req MGetGroupPowerReq
	if err := c.ShouldBindQuery(&req); err != nil {
		return myCtx, err
	}
	groupPowers, err := groupPower_m.MGetGroupPowerInfoMap(model, req.Ids)
	if err != nil {
		return myCtx, err
	}
	groupPowerUsers, err := groupPower_m.MGetGroupPowerUsers(model, req.Ids)
	if err != nil {
		return myCtx, err
	}
	groupPowerGrade, err := groupPower_m.MGetGroupPowerGrade(model, req.Ids)
	if err != nil {
		return myCtx, err
	}
	response := make(map[mysql.ID]group_power_cv.CvGroupPowerInfo)
	for groupPowerId, info := range groupPowers {
		// 成员上限
		var memberMax mysql.Num
		grade := groupPowerGrade[groupPowerId].Grade
		if grade >= groupPower_e.GroupPowerGrade0 && grade <= groupPower_e.GroupPowerGradeMax {
			//memberMax = mysql.Num(group_power_cv.GroupPowerGradePrivilegeNum[groupPowerGrade[groupPowerId].Grade][0].Num)
			memberMax = mysql.Num(group_power_s.GetGroupPowerMaxMemberNum(model, groupPowerId, grade))
		}
		memberNum := mysql.Num(len(groupPowerUsers[groupPowerId]))
		if memberNum > memberMax {
			memberMax = memberNum
		}
		response[groupPowerId] = group_power_cv.CvGroupPowerInfo{
			CvGroupPowerBase: group_power_cv.CvGroupPowerBase{
				Id:        groupPowerId,
				Icon:      info.Icon,
				Name:      info.Name,
				Nameplate: info.Nameplate,
			},
			CvGroupPowerMember: group_power_cv.CvGroupPowerMember{
				MemberNum: memberNum,
				MemberMax: memberMax,
			},
			CvGroupPowerGrade: group_power_cv.CvGroupPowerGrade{
				Grade: grade,
				Exp:   groupPowerGrade[groupPowerId].Exp,
			},
		}
	}
	resp.ResponseOk(c, response)
	return myCtx, nil
}

func Test(c *gin.Context) (*mycontext.MyContext, error) {
	var model = domain.CreateModelNil()
	if err := msg_m.NewUserRecord(model, 4549, msg_e.GroupPowerExpireNotice, "", 4549, "", "", "", "", "").Persistent(); err != nil {
		return nil, err
	}
	mgrUser, _ := user_m.GetUser(model, 4549)
	err := msg_m.SendEmasMsgAssistant(model, mgrUser.ExternalId, mgrUser.DeviceType)
	if err != nil {
		return nil, err
	}
	//err := emas.SendIosMsgAll("全部消息测试")
	//if err != nil {
	//	return nil, err
	//}
	return nil, nil
}

type GroupPowerDayStar struct {
	Date         time.Time
	GroupPowerId uint64
	Type         groupPower_e.GroupPowerStarType
	UserId       uint64
	Score        uint64
}

// @Tags 国家势力-内部
// @Summary 同步家族之星到redis
// @Success 200
// @Router /inner/groupPower/sync/star [get]
func SyncStar(c *gin.Context) (*mycontext.MyContext, error) {
	myCtx := mycontext.CreateMyContext(c.Keys)
	t := time.Now()
	start := c.Query("start")
	end := c.Query("end")
	if len(start) <= 0 || len(end) <= 0 {
		return myCtx, bizerr.InvalidParameter
	}
	var model = domain.CreateModelContext(myCtx)
	var stars []GroupPowerDayStar
	if err := model.DB().Table("group_power_day_star").
		Select("`date`,group_power_id,type,user_id,SUM(score) score").
		Where("`date` BETWEEN ? AND ?", start, end).
		Group("`date`,group_power_id,type,user_id").Find(&stars).Error; err != nil {
		model.Log.Errorf("SyncStar fail:%v", err)
		return myCtx, err
	}
	ttl := map[string]time.Duration{
		"day":   time.Hour * 24 * 7,
		"week":  time.Hour * 24 * 7 * 30,
		"month": time.Hour * 24 * 7 * 30 * 2,
	}
	num := len(stars)
	for i, star := range stars {
		for _, period := range []string{"day", "week", "month"} {
			var dateStr string
			switch period {
			case "day":
				dateStr = star.Date.Format("2006-01-02")
			case "week":
				dateStr = now.With(star.Date).BeginningOfWeek().Format("2006-01-02")
			case "month":
				dateStr = now.With(star.Date).BeginningOfMonth().Format("2006-01-02")
			}
			key := groupPower_k.GetGroupPowerStarRankKey(star.Type, period, star.GroupPowerId, dateStr)
			model.RedisCluster.ZIncrBy(model, key, float64(star.Score), fmt.Sprintf("%d", star.UserId))
			model.RedisCluster.Expire(model, key, ttl[period])
			model.Log.Infof("SyncStar i:%v,star:%v", i, star)
		}
	}
	type res struct {
		Num  int
		Cost float64
	}
	resp.ResponseOk(c, res{
		Num:  num,
		Cost: time.Now().Sub(t).Seconds(),
	})
	return myCtx, nil
}