package player

import (
	"context"
	"fmt"
	jsoniter "github.com/json-iterator/go"
	"github.com/mhaya/game/game_cluster/internal/code"
	"github.com/mhaya/game/game_cluster/internal/constant"
	"github.com/mhaya/game/game_cluster/internal/data"
	"github.com/mhaya/game/game_cluster/internal/mdb"
	"github.com/mhaya/game/game_cluster/internal/mdb/models"
	"github.com/mhaya/game/game_cluster/internal/param"
	clog "github.com/mhaya/logger"
	"sort"
	"strconv"
	"strings"
)

func (p *actorPlayer) botInvite() {
	pid := mdb.RDB.Get(context.Background(), fmt.Sprintf("%v:1:%v", constant.InviteKey, p.Player.OpenId)).Val()
	clog.Debugf("[Init] newUser pid = %s", pid)
	if pid == "" {
		return
	}
	//如果邀请是自己不处理
	if p.Player.UserName == pid {
		return
	}
	p.Player.Pid = pid
	p.Player.SetInvite(pid)
	clog.Infof("player invite,playerName：%v, inviteName：%v", p.Player.UserName, pid)
}

func (p *actorPlayer) invite(req *param.InviteReq) int32 {
	clog.Debugf("invite execute => parenName = ", req.ParentName)
	if !p.isOnline {
		clog.Infof("[invite] PlayerNotLogin err node=%v", p.App().NodeId())
		return code.PlayerNotLogin
	}
	if p.Player.Pid != "" {
		return code.InviteEmpoweringOthersError
	}

	exists := mdb.RDB.Exists(context.Background(), fmt.Sprintf("%v:1:%v", constant.InviteKey, p.Player.UserName)).Val()
	if exists > 0 {
		return code.Error
	}

	//如果邀请是自己不处理
	if p.Player.UserName == req.ParentName {
		return code.InviteEmpoweringOthersError
	}

	//req.ParentName 是邀请玩家id
	p.dirty = true
	p.Player.Pid = req.ParentName
	clog.Debugf("invite execute => p.Player.Pid = p.Player.Pid = ", p.Player.Pid)
	p.Player.SetInvite(req.ParentName)
	//添加日志

	clog.Infof("player invite，playerName：%v, inviteName：%v", p.Player.UserName, req.ParentName)

	return code.OK
}

func (p *actorPlayer) inviteRecord() (*param.WeeklyRankConfigResp, int32) {
	if !p.isOnline {
		clog.Infof("[inviteRecord] PlayerNotLogin err node=%v", p.App().NodeId())
		return nil, code.PlayerNotLogin
	}
	var resp param.WeeklyRankConfigResp
	if d, ok := p.Player.Invite[models.InvitePlayer]; ok {
		resp.InviteNum = d.Num
		for _, v := range d.Reward {
			resp.InviteTotalReward = append(resp.InviteTotalReward, data.ItemReward{ItemID: v.ItemID, ItemBaseType: v.ItemBaseType, Amount: v.Amount})
		}
	}
	if d, ok := p.Player.Invite[models.InviteVipPlayer]; ok {
		resp.VipInviteNum = d.Num
		for _, v := range d.Reward {
			resp.VipInviteTotalReward = append(resp.VipInviteTotalReward, data.ItemReward{ItemID: v.ItemID, ItemBaseType: v.ItemBaseType, Amount: v.Amount})
		}
	}

	return &resp, code.OK
}

/*func (p *actorPlayer) inviteReward(req *param.InviteReq) (*int, int32) {
	if !p.isOnline {
		p.InitBase(req.ParentName)
	}
	p.dirty = true
	p.isOnline = true
	addItem := models.NewAddItem()
	switch req.Type {
	case models.InvitePlayer:
		ret, ok := data.DiscreteRuleConfig.Get(models.InvitePlayer)
		if !ok {
			return &p.Player.IsLeader, code.Error
		}
		addItem.Add(ret.Reward)
		p.Player.Item.AddItem(ret.Reward)
		addItem.AddById(models.ItemInvite, 1)
		p.Player.SetPlayerRewardLog(models.SourceInvite, models.InvitePlayer, ret.Reward, []data.ItemReward{}, 2)
	case models.InviteVipPlayer:
		ret, ok := data.DiscreteRuleConfig.Get(models.InviteVipPlayer)
		if !ok {
			return &p.Player.IsLeader, code.Error
		}
		addItem.Add(ret.Reward)
		p.Player.Item.AddItem(ret.Reward)
		addItem.AddById(models.ItemInvite, 1)
		p.Player.SetPlayerRewardLog(models.SourceInvite, models.InviteVipPlayer, ret.Reward, []data.ItemReward{}, 2)
	}
	//社区长邀请
	if p.Player.IsLeader == 1 {
		ret, ok := data.DiscreteRuleConfig.Get(models.InvitePlayerByLeader)
		if !ok {
			return &p.Player.IsLeader, code.Error
		}
		addItem.Add(ret.Reward)
		p.Player.Item.AddItem(ret.Reward)
		p.Player.SetPlayerRewardLog(models.SourceInvite, models.InvitePlayerByLeader, ret.Reward, []data.ItemReward{}, 2)
	}
	//设置邀请榜单
	models.SetRank(constant.RankSourceInvite, p.Player.IsRobot, p.Player.UserName, 1)

	p.Player.LevelUp()

	p.Player.FinishAchieveTaskByType2()

	return &p.Player.IsLeader, code.OK
}

*/

// 邀请裂变奖励查询
func (p *actorPlayer) inviteRewardRatio() (*param.InviteRatioResp, int32) {
	if !p.isOnline {
		clog.Infof("[inviteRewardRatio] PlayerNotLogin err node=%v", p.App().NodeId())
		return nil, code.PlayerNotLogin
	}
	key := fmt.Sprintf("%v:1:%v", constant.InviteScoreKey, p.Player.UserName)
	return p.inviteRewardList(key, false)
}

// 邀请裂变好友累计奖励
func (p *actorPlayer) inviteRewardRatioHistory() (*param.InviteRatioResp, int32) {
	if !p.isOnline {
		clog.Infof("[inviteRewardRatioHistory] PlayerNotLogin err node=%v", p.App().NodeId())
		return nil, code.PlayerNotLogin
	}
	key := fmt.Sprintf("%v:1:%v", constant.InviteRatioRecordKey, p.Player.UserName)
	return p.inviteRewardList(key, true)
}

func (p *actorPlayer) inviteRewardList(key string, isHistory bool) (*param.InviteRatioResp, int32) {
	inviteReword, _ := data.DiscreteRuleConfig.Get(models.InviteRatio)
	split := strings.Split(inviteReword.Condition, ",")
	ratio, _ := strconv.ParseFloat(split[0], 64)
	minClaim, _ := strconv.Atoi(split[1])

	result, _ := mdb.RDB.HGetAll(context.Background(), key).Result()

	claimSlice := make([]param.InviteRatioClaim, 0)
	var totalAmount int64

	// 默认好有
	default_friend := []int{2001, 2002, 2003}
	for _, id := range default_friend {
		row, _ := data.DiscreteRuleConfig.Get(id)
		if row == nil {
			continue
		}
		firstRewardItem := p.Player.FirstClaimReward[id]
		if _, exist := p.Player.FirstClaimReward[id]; !exist {
			continue
		}
		if firstRewardItem.IsClaim == 1 && !isHistory {
			continue
		}

		num := firstRewardItem.Reward[0].Amount
		claim := param.InviteRatioClaim{
			UserName: row.Condition,
			Avatar:   "",
			ClaimNum: int64(num),
			NickName: row.Condition,
		}
		claimSlice = append(claimSlice, claim)
		totalAmount += int64(num)
	}

	for k, v := range result {
		num, _ := strconv.Atoi(v)

		if num <= minClaim {
			continue
		}

		info := mdb.RDB.HGet(context.Background(), constant.PlayerBaseKey, k).Val()
		var playerBase param.PlayerBase
		jsoniter.Unmarshal([]byte(info), &playerBase)

		claim := param.InviteRatioClaim{
			UserName: k,
			Avatar:   playerBase.Avatar,
			ClaimNum: int64(num),
			NickName: playerBase.NickName,
		}
		claimSlice = append(claimSlice, claim)
		totalAmount += int64(num)
	}

	return &param.InviteRatioResp{
		Ratio:       ratio,
		ClaimSlice:  claimSlice,
		TotalAmount: totalAmount,
	}, code.OK
}

// 邀请奖励查询
func (p *actorPlayer) inviteNodeReward() (*models.InviteNodeReward, int32) {
	if !p.isOnline {
		clog.Infof("[inviteNodeReward] PlayerNotLogin err node=%v", p.App().NodeId())
		return nil, code.PlayerNotLogin
	}

	key := fmt.Sprintf("%v:%v:%v", constant.InviteKey, models.InvitePlayer, p.Player.UserName)
	// 当前邀请人数
	lRange, _ := mdb.RDB.LRange(context.Background(), key, 0, -1).Result()
	curInviteNum := len(lRange)
	// 历史刷新周期已领取奖励的邀请人数
	key2 := fmt.Sprintf("%v:%v", constant.InviteNodeHistoryKey, p.Player.UserName)
	historyNum, _ := mdb.RDB.Get(context.Background(), key2).Int()
	// 当前周期的有效邀请人数
	validNum := curInviteNum - historyNum

	var curCondition int
	var keys []int
	for _, item := range p.Player.InviteNodeReward {
		keys = append(keys, item.ID)
	}
	sort.Ints(keys)
	for _, id := range keys {
		curCondition += p.Player.InviteNodeReward[id].Condition
		if validNum >= curCondition {
			p.Player.InviteNodeReward[id].IsUnlock = 1
		} else {
			p.Player.InviteNodeReward[id].IsUnlock = 0
		}
	}
	return &p.Player.InviteNodeReward, code.OK
}
