package smallrocket

import (
	"fmt"
	rule "mongo.games.com/game/gamerule/smallrocket"
	"mongo.games.com/game/gamesrv/base"
	"mongo.games.com/game/proto"
	"mongo.games.com/game/protocol/smallrocket"
	"mongo.games.com/goserver/core/logger"
	"strconv"
)

type PlayerEx struct {
	*base.Player //玩家信息

	betData    []*rule.BetDataEx // 下注信息
	CurBetData []*rule.BetDataEx // 本局的下注信息
	gainCoin   int64             // 本局赢的金币
	taxCoin    int64             // 本局税收
	odds       int32
}

func (this *PlayerEx) Clear(baseScore int32) {
	this.UnmarkFlag(base.PlayerState_WaitNext)
	this.UnmarkFlag(base.PlayerState_GameBreak)
	this.MarkFlag(base.PlayerState_Ready)

	this.gainCoin = 0
	this.taxCoin = 0
	this.odds = 0

	this.betData = make([]*rule.BetDataEx, 2)
	this.CurBetData = make([]*rule.BetDataEx, 2)

	this.InitBetData(baseScore)
}

func (this *PlayerEx) CanOp(sceneEx *SceneEx) bool {
	if !this.IsGameing() {
		logger.Logger.Trace("(this *PlayerEx) CanOp return false ", this.SnId)
		return false
	}
	return true
}

// 按下注位置检查能否下注
func (this *PlayerEx) CanBetCoinByPos(betPos int, betVal int64) bool {
	if len(this.betData) >= 2 && betPos <= 1 {
		if this.GetCoin() >= betVal {
			return true
		}
	}

	return false
}

// 检查金币能否够下注
func (this *PlayerEx) CanBetCoin() bool {
	if len(this.betData) >= 2 {
		var betCoins int64 = 0
		for i := 0; i <= len(this.betData); i++ {
			betCoins += this.betData[i].BetVal
		}

		if this.Coin >= betCoins {
			return true
		}
	}

	return false
}

// 游戏新一局 设置数据
func (this *PlayerEx) ReStartGame() {
	this.ReBetDataStartGame()
	this.gainCoin = 0
	this.taxCoin = 0
	this.odds = 0
}

// 金币不够停止下注
func (this *PlayerEx) StopBetCoinByPos(betPos int) {

	logger.Logger.Trace("(this *PlayerEx) StopBetCoinByPos SnId: ", this.SnId, " | betPos:", betPos)

	if len(this.betData) >= 2 && betPos <= 1 {

		if this.betData[betPos].IsAutoBetAndTake {

			params := make([]int64, 10)
			params[0] = int64(betPos)
			pack := &smallrocket.SCSmallRocketOp{
				SnId:      proto.Int32(this.SnId),
				OpCode:    proto.Int32(int32(rule.SmallRocketPlayerOpStopAutoBet)),
				Params:    params,
				OpRetCode: smallrocket.OpResultCode_OPRC_CoinNotEnough,
			}

			if this.betData != nil {
				for i := 0; i < len(this.betData); i++ {

					tempBetEml := &smallrocket.BetDataInfo{
						BetVal:           proto.Int64(this.betData[i].BetVal),
						TakeMul:          proto.Float32(float32(this.betData[i].TakeMul)),
						IsCurBet:         proto.Bool(false),
						IsNextBet:        proto.Bool(false),
						IsTakeGain:       proto.Bool(false),
						IsAutoBetAndTake: proto.Bool(false),
					}

					pack.BetDataArr = append(pack.BetDataArr, tempBetEml)
				}
			}

			this.SendToClient(int(smallrocket.SmallRocketPacketID_PACKET_SC_SMALLROCKET_PLAYEROP), pack)
		}

		this.betData[betPos].IsCurBet = false
		this.betData[betPos].IsNextBet = false
		this.betData[betPos].IsAutoBetAndTake = false
		this.betData[betPos].IsTakeGain = false
	}
}

// 停止不能下注的
func (this *PlayerEx) StopBetCoin() (betPos0 bool, betPos1 bool) {

	if len(this.betData) >= 2 {
		BetCoin0Val := this.betData[0].BetVal
		BetCoin1Val := this.betData[1].BetVal

		logger.Logger.Trace("(this *PlayerEx) StopBetCoin SnId:", this.SnId, " | Coin:", this.Coin, " | BetCoin0Val:", BetCoin0Val, " | BetCoin1Val:", BetCoin1Val)

		if this.betData[0].IsCurBet && this.betData[1].IsCurBet {
			if this.GetCoin() <= 0 {
				this.StopBetCoinByPos(0)
				this.StopBetCoinByPos(1)
				return true, true
			}

			// 两个押注都够，什么也不做
			if (BetCoin0Val + BetCoin1Val) <= this.Coin {
				return false, false
			}

			// 两个押注都不够，全部停止投注
			if BetCoin0Val > this.Coin && BetCoin1Val > this.Coin {
				this.StopBetCoinByPos(0)
				this.StopBetCoinByPos(1)
				return true, true
			}

			// 两个押注之和大于 玩家所拥有金币数
			if (BetCoin0Val + BetCoin1Val) > this.Coin {
				if BetCoin0Val < this.Coin && BetCoin1Val < this.Coin {
					if BetCoin0Val >= BetCoin1Val {
						this.StopBetCoinByPos(1)
						betPos0 = false
						betPos1 = true
					} else {
						this.StopBetCoinByPos(0)
						betPos0 = true
						betPos1 = false
					}
					return
				}

				if BetCoin0Val <= this.Coin || BetCoin1Val <= this.Coin {
					if BetCoin0Val > this.Coin {
						this.StopBetCoinByPos(0)
						betPos0 = false
						betPos1 = true
					}

					if BetCoin1Val > this.Coin {
						this.StopBetCoinByPos(1)
						betPos0 = false
						betPos1 = true
					}

					return betPos0, betPos1
				}
			}
		} else if this.betData[0].IsCurBet && !this.betData[1].IsCurBet {
			if BetCoin0Val > this.Coin {
				this.StopBetCoinByPos(0)
			}
		} else if !this.betData[0].IsCurBet && this.betData[1].IsCurBet {
			if BetCoin1Val > this.Coin {
				this.StopBetCoinByPos(1)
			}
		}
	}

	return false, false
}

// 不在线的玩家停止自动下注
func (this *PlayerEx) StopLineAutoBetCoin() {
	if this.IsOnLine() {
		return
	}

	if len(this.betData) >= 2 {
		for i := 0; i < len(this.betData); i++ {
			if this.betData[i].IsAutoBetAndTake || this.betData[i].IsCurBet {
				this.betData[i].IsAutoBetAndTake = false
				this.betData[i].IsCurBet = false
				this.betData[i].IsNextBet = false

				this.betData[i].ReStartGame()
				logger.Logger.Trace("(this *PlayerEx) StopLineAutoBetCoin SnId:", this.SnId, " betPos:", i)
			}
		}
	}
}

// 初始化下注数据
func (this *PlayerEx) InitBetData(baseScore int32) {

	for i := 0; i < len(this.betData); i++ {

		TakeMul, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", 1.20), 64)
		this.betData[i] = &rule.BetDataEx{
			BetVal:           int64(baseScore),
			TakeMul:          TakeMul,
			IsCurBet:         false,
			IsNextBet:        false,
			IsTakeGain:       false,
			IsAutoBetAndTake: false,
		}
	}

	for i := 0; i < len(this.betData); i++ {

		TakeMul, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", 1.20), 64)
		this.CurBetData[i] = &rule.BetDataEx{
			BetVal:           int64(baseScore),
			TakeMul:          TakeMul,
			IsCurBet:         false,
			IsNextBet:        false,
			IsTakeGain:       false,
			IsAutoBetAndTake: false,
		}
	}
}

func (this *PlayerEx) CopyToCurBetData() {

	for i := 0; i < len(this.betData); i++ {
		this.CurBetData[i].BetVal = this.betData[i].BetVal
		this.CurBetData[i].TakeMul = this.betData[i].TakeMul
		this.CurBetData[i].IsCurBet = this.betData[i].IsCurBet
		this.CurBetData[i].IsNextBet = this.betData[i].IsNextBet
		this.CurBetData[i].IsTakeGain = this.betData[i].IsTakeGain
		this.CurBetData[i].IsAutoBetAndTake = this.betData[i].IsAutoBetAndTake
		this.CurBetData[i].GainSearchTime = this.betData[i].GainSearchTime
		this.CurBetData[i].GainCoinMul = this.betData[i].GainCoinMul

	}
}

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

	if len(this.CurBetData) >= 2 {
		for i := 0; i < len(this.CurBetData); i++ {
			this.CurBetData[i].Reset()
		}
	}
}

// 游戏新一局 设置下注数据
func (this *PlayerEx) ReBetDataStartGame() {
	if len(this.betData) >= 2 {
		for i := 0; i < len(this.betData); i++ {
			this.betData[i].ReStartGame()
		}
	}

	if len(this.CurBetData) >= 2 {
		this.CopyToCurBetData()
	}
}

// 玩家设置自动
func (this *PlayerEx) SetAutoBetAndTake(isAutoBet int64, betPos int64) {
	if len(this.betData) >= 2 && betPos <= 1 {

		if isAutoBet == 1 {
			this.betData[betPos].IsAutoBetAndTake = true
		} else if isAutoBet == 0 {
			this.betData[betPos].IsAutoBetAndTake = false
		}
	}
}

func (this *PlayerEx) GetAutoBetAndTake(betPos int64) bool {
	if len(this.betData) >= 2 && betPos <= 1 {
		return this.betData[betPos].IsAutoBetAndTake
	}

	return false
}

func (this *PlayerEx) IsAutoBetAndTakeByPos(betPos int64) bool {
	if len(this.betData) >= 2 && betPos <= 1 {
		return this.betData[betPos].IsAutoBetAndTake
	}

	return false
}

func (this *PlayerEx) IsAutoBetAndTake() bool {
	if len(this.betData) >= 2 {
		for i := 0; i < len(this.betData); i++ {
			if this.betData[i].IsAutoBetAndTake {
				return true
			}
		}
	}

	return false
}

func (this *PlayerEx) CanPlayerOpInState(sceneState int, betPos int) bool {
	if len(this.betData) < 2 || betPos > 1 {
		return false
	}

	return false
}

// 玩家自动下注
func (this *PlayerEx) PlayerAutoBet(sceneState int) {

	if len(this.betData) >= 2 {
		for i := 0; i < len(this.betData); i++ {
			if sceneState == rule.SmallRocketSceneStateStart {
				if this.betData[i].IsAutoBetAndTake {
					this.betData[i].IsCurBet = true
					this.betData[i].IsTakeGain = false
				}
			} else if sceneState == rule.SmallRocketSceneStatePlayGame {
				if this.betData[i].IsAutoBetAndTake {
					this.betData[i].IsNextBet = true
				}
			}
		}
	}
}

// 能否退出游戏
func (this *PlayerEx) CanLeaveScene(sceneState int) bool {

	if len(this.betData) >= 2 {
		for i := 0; i < len(this.betData); i++ {
			if sceneState == rule.SmallRocketSceneStateStart {
				if this.betData[i].IsCurBet && !this.betData[i].IsTakeGain {
					return false
				}
			} else if sceneState == rule.SmallRocketSceneStatePlayGame {
				if this.betData[i].IsCurBet && !this.betData[i].IsTakeGain {
					return false
				}
			}
		}
	}

	return true
}

// 本局是否领取过押注奖励
func (this *PlayerEx) IsFinishTakeBet(sceneState int) bool {

	if len(this.betData) >= 2 {
		for i := 0; i < len(this.betData); i++ {
			if sceneState == rule.SmallRocketSceneStatePlayGame {
				if this.betData[i].IsCurBet && this.betData[i].IsTakeGain {
					return true
				}
			}
		}
	}

	return false
}

func (this *PlayerEx) PrintBetData(sceneState int) {
	if sceneState == rule.SmallRocketSceneStateStart {
		logger.Logger.Trace("StateStart: PrintBetData")
	} else if sceneState == rule.SmallRocketSceneStatePlayGame {
		logger.Logger.Trace("PlayGame: PrintBetData")
	} else if sceneState == rule.SmallRocketSceneStateBilled {
		logger.Logger.Trace("StateBilled: PrintBetData")
	}

	if len(this.betData) >= 2 {
		for i := 0; i < len(this.betData); i++ {
			logger.Logger.Trace("SnId:", this.SnId, " Name: ", this.Name, "PlayerEx-----betData[", i, "]:", *this.betData[i])
			// logger.Logger.Trace("SnId:", this.SnId, "   PlayerEx-----betData: ", *this.betData[i])
		}

	}
}
