package jackpot

import (
	"fmt"
	"game/common/model/jackpot"
	"github.com/fox/fox/log"
	"github.com/go-redis/redis/v8"
)

type JackPotMgr struct {
	gameId      int
	jackpotUser map[int64]int64 // 中jackpot玩家，key:玩家id value:投注额bet
	rdb         *redis.Client
}

func NewJackpotMgr(gameId int, rdb *redis.Client) *JackPotMgr {
	mgr := &JackPotMgr{}
	mgr.gameId = gameId
	mgr.rdb = rdb
	return mgr
}

// true:出现垫资
func (m *JackPotMgr) Load(initJp int64) bool {
	if jackpot.JackpotGet(m.rdb, m.gameId) < initJp {
		return true
	}
	return false
}

func (m *JackPotMgr) resetJackpot(initJp int64) int64 {
	jackpot.JackpotAdd(m.rdb, m.gameId, initJp)
	count := jackpot.JackpotInitCountAdd(m.rdb, m.gameId)
	system := jackpot.JackpotSystemAdd(m.rdb, m.gameId, -initJp)
	log.Info(fmt.Sprintf("game:%v gameid:%v jackpot已被掏空，重置为:%v 重置次数:%v 系统盈亏:%v", m.gameId, m.gameId, initJp, count, system))
	return initJp
}

func (m *JackPotMgr) GetJackpot() int64 {
	return jackpot.JackpotGet(m.rdb, m.gameId)
}

// jpXRate:赎回比例 jpYRate:追加比例
func (m *JackPotMgr) AddJp(loseBet, jpXRate, jpYRate, jpXYRate int64) (jpX, jpY int64) {
	if loseBet == 0 {
		return
	}
	// jackpot池追加资金、玩家赎回资金(让庄家jp池垫的钱回归0)、庄家总垫资
	var jpAdd, userRepaid, sysValue int64
	if sysValue = jackpot.JackpotSystemGet(m.rdb, m.gameId); sysValue < 1 {
		userRepaid = loseBet * jpXRate / 10000
		jpAdd = loseBet * jpYRate / 10000
		sysValue = jackpot.JackpotSystemAdd(m.rdb, m.gameId, userRepaid)
		_ = jackpot.JackpotUserRepaidAdd(m.rdb, m.gameId, userRepaid)
	} else {
		jpAdd = loseBet * jpXYRate / 10000
	}
	log.Debug(fmt.Sprintf("%v进入系统池,%v进入jackpot池，系统池盈亏:%v", userRepaid, jpAdd, sysValue))
	return userRepaid, jpAdd
}

// 回滚。funding:垫资,jpX:赎回 jpY:追加
func (m *JackPotMgr) RollBackJpXAndJpY(lastJackpot, funding, jpX, jpY int64) {
	log.Debug(fmt.Sprintf("分出去的jackpot:%v,当前jackpot池:%v 需要回退的垫资:%v 需要回退的赎回jpx:%v 需要回退的追加jpy:%v",
		lastJackpot, jackpot.JackpotGet(m.rdb, m.gameId), funding, jpX, jpY))

	jpv := jackpot.JackpotAdd(m.rdb, m.gameId, -jpY)
	sys := jackpot.JackpotSystemAdd(m.rdb, m.gameId, -jpX)
	repaid := jackpot.JackpotUserRepaidAdd(m.rdb, m.gameId, -jpX)
	log.Debug(fmt.Sprintf("当前系统池:%v，赎回值:%v", sys, repaid))
	if lastJackpot == 0 {
		return
	}
	jackpot.JackpotSet(m.rdb, m.gameId, lastJackpot)
	jpv = jackpot.JackpotAdd(m.rdb, m.gameId, -jpY)
	jpv = jackpot.JackpotGet(m.rdb, m.gameId)
	sys = jackpot.JackpotSystemAdd(m.rdb, m.gameId, funding)
	log.Debug(fmt.Sprintf("当前系统池:%v，赎回值:%v jackpot值:%v", sys, repaid, jpv))
}

// 中jackpot玩家
func (m *JackPotMgr) AddJpUser(userId, bet int64) {
	if jpBet, ok := m.jackpotUser[userId]; ok {
		m.jackpotUser[userId] = jpBet + bet
	} else {
		m.jackpotUser[userId] = bet
	}
}

// 返回map[中奖玩家]奖金,总jackpot值
func (m *JackPotMgr) WinJackpot() (map[int64]int64, int64) {
	if len(m.jackpotUser) == 0 {
		return nil, 0
	}
	jpV := jackpot.JackpotGet(m.rdb, m.gameId)
	// totalJpBet := int64(0)
	// for _, bet := range m.jackpotUser {
	// 	totalJpBet += bet
	// }
	// jpRate := jackpot / totalJpBet
	// log.Debug("jackpot:", jackpot, " totalJpBet:", totalJpBet, " jpRate:", jpRate)
	// winUser := make(map[int64]int64)
	// for userId, bet := range m.jackpotUser {
	// 	winUser[userId] = bet * jpRate
	// }

	userJp := jpV / int64(len(m.jackpotUser))
	log.DebugF("jackpot:%v 每个玩家分jp:%v. 清空jackpot池", userJp, userJp)
	winUser := make(map[int64]int64)
	for userId := range m.jackpotUser {
		winUser[userId] = userJp
	}
	jackpot.JackpotSet(m.rdb, m.gameId, 0)
	m.jackpotUser = make(map[int64]int64)
	return winUser, jpV
}
