package smallrocket

import (
	"fmt"
	"math"
	"math/rand"
	"mongo.games.com/game/srvdata"
	"mongo.games.com/goserver/core/logger"
	"strconv"
	"time"
)

type Logic struct {
	BoomMul float64

	BombTimeToMulArr []*BombTimeToMul
	BombMulToTimeArr []*BombMulToTime
}

func (this *Logic) init() {
	if this.BombTimeToMulArr == nil {
		this.BombTimeToMulArr = make([]*BombTimeToMul, 0)
	}

	if this.BombMulToTimeArr == nil {
		this.BombMulToTimeArr = make([]*BombMulToTime, 0)
	}
}

// 重置下注信息
func (this *Logic) ResetBetData(betData []*BetDataEx) {
	if len(betData) >= 2 {
		for i := 0; i < len(betData); i++ {
			betData[i].Reset()
		}
	}
}

// 火箭爆炸倍数
func (l *Logic) CalBoomMul(e int) (float64, int) {
	h := rand.Intn(e)

	fh := float64(h)
	fe := float64(e)

	return math.Floor((96*fe)/(fe-fh)) / 100.00, h
}

// 火箭爆炸倍数
func (l *Logic) CalBoomTime(p int) float64 {
	fp := float64(p)
	//q := 100000000.00
	pp := 400000.00
	ppp := 20000.00
	score := 0.0
	for {
		if pp+ppp > float64(SmallRocketBombRandomMulMaxE) {
			pp += ppp * (fp - pp) / fp
			score = fp / (fp - pp)

			break
		}
	}
	logger.Logger.Trace("score=", score)
	return score
}

// 本局是否下注
func (l *Logic) IsCurRoundBet(betData []*BetDataEx) bool {
	if len(betData) >= 2 {
		if betData[0].IsCurBet || betData[1].IsCurBet {
			return true
		} else {
			return false
		}
	}
	return false
}

// 本局的子下注位置否下注
func (l *Logic) IsCurRoundBetPos(betData []*BetDataEx, betPos int64) bool {
	if len(betData) >= 2 {
		return betData[betPos].IsCurBet
	}
	return false
}

// 下一局位置否下注
func (l *Logic) IsNextRoundBet(betData []*BetDataEx) bool {
	if len(betData) >= 2 {
		if betData[0].IsNextBet || betData[1].IsNextBet {
			return true
		} else {
			return false
		}
	}
	return false
}

// 下一局的子下注位置否下注
func (l *Logic) IsNextRoundBetPos(betData []*BetDataEx, betPos int64) bool {
	if len(betData) >= 2 && betPos <= 1 {
		return betData[betPos].IsNextBet
	}
	return false
}

// 获取本局下注总金额
func (l *Logic) GetRoundBetCoin(betData []*BetDataEx) float64 {
	if !l.IsCurRoundBet(betData) {
		return 0
	}

	var retBetCoin float64 = 0
	if len(betData) >= 2 {
		if betData[0].IsCurBet {
			retBetCoin += float64(betData[0].BetVal)
		}

		if betData[1].IsCurBet {
			retBetCoin += float64(betData[1].BetVal)
		}
	}

	return retBetCoin
}

// 本局金币收益
func (l *Logic) GetRoundGainCoin(betData []*BetDataEx, bombMul float64) float64 {
	if !l.IsCurRoundBet(betData) {
		return 0
	}

	var retGainCoin float64 = 0
	if len(betData) >= 2 {
		if betData[0].IsCurBet && !betData[0].IsTakeGain {
			retGainCoin += float64(betData[0].BetVal) * (bombMul - 1.0)
		}

		if betData[1].IsCurBet && !betData[1].IsTakeGain {
			retGainCoin += float64(betData[1].BetVal) * (bombMul - 1.0)
		}
	}

	return retGainCoin
}

// 本局是否所有奖励都已领取
func (this *Logic) IsExistRoundTakenGain(betData []*BetDataEx) bool {

	if len(betData) >= 2 {
		if betData[0].IsCurBet && !betData[0].IsTakeGain {
			return false
		}

		if betData[1].IsCurBet && !betData[1].IsTakeGain {
			return false
		}
	}
	return true
}

// 加载火箭时间和倍数数据
func (this *Logic) LoadCrashSearchData() {

	dbItemArr := srvdata.PBDB_CrashSearchMgr.Datas.Arr

	logger.Logger.Trace("(this *Logic) LoadCrashSearchData: dbItemArr.Len: ", len(dbItemArr))
	if dbItemArr != nil {
		if this.BombTimeToMulArr == nil {
			this.BombTimeToMulArr = make([]*BombTimeToMul, 0, 5120)
		}

		if this.BombMulToTimeArr == nil {
			this.BombMulToTimeArr = make([]*BombMulToTime, 0, 5120)
		}

		preTime := 0
		preMul := 0
		for _, dbItem := range dbItemArr {

			this.BombTimeToMulArr = append(this.BombTimeToMulArr, &BombTimeToMul{int32(preTime), dbItem.GetTime(), dbItem.GetPrice()})

			this.BombMulToTimeArr = append(this.BombMulToTimeArr, &BombMulToTime{int32(preMul), dbItem.GetPrice(), dbItem.GetTime()})

			preTime = int(dbItem.GetTime())
			preMul = int(dbItem.GetPrice())

		}

		logger.Logger.Trace("(this *Logic) LoadCrashSearchData: BombTimeToMulArr.Len: ", len(this.BombTimeToMulArr))
		logger.Logger.Trace("(this *Logic) LoadCrashSearchData: BombMulToTimeArr.Len: ", len(this.BombMulToTimeArr))
	}
}

// 通过火箭倍数找到火箭爆炸时间
func (this *Logic) GetBombTimeByBombMul(bombMulSearch int32) int32 {

	//logger.Logger.Trace("(this *Logic) GetBombTimeByBombMul: In , bombMulSearch:", bombMulSearch)

	if this.BombMulToTimeArr == nil {
		return 0
	}

	//for i := 0; i <= len(this.BombMulToTimeArr); i++ {
	//	//if BombMulToTimeArr
	//	if bombMulSearch > mulItem.MinBombMul && bombMulSearch <= mulItem.MaxBombMul {
	//
	//	}
	//}

	//logger.Logger.Trace("(this *Logic) GetBombTimeByBombMul: BombMulToTimeArr.Len: ", len(this.BombMulToTimeArr))

	for _, mulItem := range this.BombMulToTimeArr {
		if bombMulSearch > mulItem.MinBombMul && bombMulSearch <= mulItem.MaxBombMul {
			return mulItem.BombTime
		}
	}

	logger.Logger.Trace("(this *Logic) GetBombTimeByBombMul: Not Found ")
	return 0
}

// 通过火箭爆炸时间找到火箭倍数
func (this *Logic) GetBombMulByBombTime(BombTime int32) int32 {
	if this.BombTimeToMulArr == nil {
		return 0
	}

	for _, mulItem := range this.BombTimeToMulArr {
		if BombTime > mulItem.MinBombTime && BombTime <= mulItem.MaxBombTime {
			return mulItem.BombMul
		}
	}

	return 0
}

// 下注信息
type BetDataEx struct {
	BetVal           int64         // 下注金额
	TakeMul          float64       // 下注领取倍数
	IsCurBet         bool          // 本局是否下注
	IsNextBet        bool          // 下一局是否下注
	IsTakeGain       bool          // 是否收取过奖励
	IsAutoBetAndTake bool          // 是否自动下注收取
	GainSearchTime   time.Duration // 自动收取时间
	GainCoinMul      float64       // 最终赢取倍数
}

// 重置
func (b *BetDataEx) Reset() {
	b.BetVal = 1000
	b.TakeMul, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", 1.20), 64)
	b.IsCurBet = false
	b.IsTakeGain = false
	b.IsNextBet = false
	b.IsAutoBetAndTake = false
	b.GainCoinMul = 0
}

// 新一局 设置数据
func (b *BetDataEx) ReStartGame() {
	b.IsCurBet = false
	b.IsTakeGain = false

	if b.IsNextBet {
		b.IsCurBet = true
	}

	if b.IsAutoBetAndTake {
		b.IsCurBet = true
	}

	b.IsNextBet = false
	b.GainCoinMul = 0
}
