package game

import (
	"encoding/json"
	"errors"
	"github.com/davy66666/poker-go/src/github.com/dolotech/leaf/gate"
	"github.com/gorilla/websocket"
	"microGame/app/usercenter/cmd/api/internal/algorithm"
	"microGame/app/usercenter/cmd/api/internal/svc"
	"microGame/app/usercenter/model/user"
	"sync"
	"time"
)

const (
	PlayerStatusInGame  int32 = 3
	PlayerStatusOffline int32 = 1
	PlayerStatusObserve int32 = 2
	PlayerStatusSitDown int32 = 0
)

type Player struct {
	*user.User
	SvcCtx *svc.ServiceContext
	mu     sync.Mutex
	Conn   *websocket.Conn
	Send   chan []byte
	cards  algorithm.Cards
	Pos    uint8 // 玩家座位号，从1开始
	status int32 // 1为离线状态

	Bet        uint32 // 当前下注
	actions    chan int32
	IsFolded   bool // 是否弃牌
	IsAllIn    bool // 是否全押
	waitAction bool

	chips     uint32 // 带入的筹码
	HandValue uint32 //手里的牌
}

func (o *Player) SetAction(n int32) error {
	if o.waitAction {
		o.actions <- n
		return nil
	}
	return errors.New("not your action")
}
func (o *Player) GetAction(timeout time.Duration) int32 {
	timer := time.NewTimer(timeout)
	o.waitAction = true
	select {
	case n := <-o.actions:
		timer.Stop()
		o.waitAction = false
		return n
	case <-timer.C:
		o.waitAction = false
		timer.Stop()
		return -1 // 超时弃牌
	}
}
func (o *Player) SetPos(pos uint8) {
	o.Pos = pos
}
func (o *Player) GetPos() uint8 {
	return o.Pos
}
func (o *Player) GetUid() int64 {
	return o.Uid
}
func (o *Player) WriteMsg(msg interface{}) {
	if o.status != PlayerStatusOffline {
		data, err := json.Marshal(msg)
		if err != nil {
			return // 适当处理错误
		}
		o.Send <- data
	}
}

func (o *Player) SetObserve() {
	o.status = PlayerStatusObserve
}

func (o *Player) IsObserve() bool {
	return o.status == PlayerStatusObserve
}

func (o *Player) SetOffline() {
	o.status = PlayerStatusOffline
}

func (o *Player) IsOffline() bool {
	return o.status == PlayerStatusOffline
}

func (o *Player) SetSitDown() {
	o.status = PlayerStatusSitDown
}

func (o *Player) IsShutdown() bool {
	return o.status == PlayerStatusSitDown
}

func (o *Player) SetGaming() {
	o.status = PlayerStatusInGame
}

func (o *Player) IsGaming() bool {
	return o.status == PlayerStatusInGame
}

func (o *Player) Replace(value *Player) {
	o.Pos = value.Pos
	o.cards = value.cards
}

func NewPlayer(data *user.User, conn gate.Agent) *Player {
	o := &Player{
		//Agent:   conn,
		actions: make(chan int32),
	}
	return o
}

//德州扑克分为以下几个阶段：
//Pre-flop：玩家手牌阶段。
//Flop：翻三张公共牌。玩法
//Turn：翻第四张公共牌。
//River：翻第五张公共牌。
//结算：根据牌型确定胜负。

//过牌（Check）：在没有人下注的情况下，选择不下注。
//下注（Bet）：如果没有人下注，可以选择下注一定金额。
//跟注（Call）：匹配其他玩家的下注金额。
//加注（Raise）：在跟注的基础上再增加下注金额。
//弃牌（Fold）：放弃继续参与该手牌。

// HandleMessage 玩家提交下注数据
// 有四种下注方式，下注数分别对应为：
// 弃牌: <0 (fold)
// 跟注：等于单注额 (call)
// 看注：= 0 表示看注 (check)
// 加注：大于单注额 (raise)
// // 全押：等于玩家手中所有筹码 (allin)
//func (o *Player) handlePlayerAction(player *Player, action string, amount int, gameState *GameState) {
//	switch action {
//	case "bet":
//		player.CurrentBet += amount
//		player.Chips -= amount
//		gameState.Pot += amount
//		if player.CurrentBet > gameState.CurrentBet {
//			gameState.CurrentBet = player.CurrentBet
//		}
//	case "fold":
//		player.IsFolded = true
//	case "all-in":
//		player.IsAllIn = true
//		gameState.Pot += player.Chips
//		player.CurrentBet += player.Chips
//		player.Chips = 0
//	}
//
//	if shouldDealCards(gameState) {
//		nextPhase(gameState)
//	}
//}
//func nextPhase(gameState *GameState) {
//	switch gameState.Phase {
//	case "pre-flop":
//		gameState.Phase = "flop"
//		dealCommunityCards(gameState, 3)
//	case "flop":
//		gameState.Phase = "turn"
//		dealCommunityCards(gameState, 1)
//	case "turn":
//		gameState.Phase = "river"
//		dealCommunityCards(gameState, 1)
//	case "river":
//		gameState.Phase = "showdown"
//		determineWinner(gameState)
//	}
//}
