package room

import (
	"server/msg"
	"sort"

	"github.com/name5566/leaf/gate"
	"github.com/name5566/leaf/log"
)

// 定一个类为每局游戏
type GameRound struct {
	// 押注总数
	TotalBet int32
	//回合列表
	Rounds []*msg.ReqRound
	ResBet *msg.ResBet
}

// RoomStatus 房间状态
const (
	RoomStatusWaiting = 0 // 等待开局
	RoomStatusDealing = 1 // 发牌中
	RoomStatusPlaying = 2 // 游戏进行中
	RoomStatusEnd     = 3 // 游戏结束
)

type Room struct {
	Id      string
	ConfId  string
	Players []*Player
	Status  int
	// 当前轮次
	Round int
	// 当前回合的座位
	RoundSitPos int
	// 每局游戏
	GameRound *GameRound
	// 牌堆
	CardDeck []*msg.ReqCard
}

type Player struct {
	Id       string
	Agent    gate.Agent
	IsRobot  bool
	UserData interface{}
	//手牌
	HandCards []*msg.ReqCard
	// 座位
	SitPos int32
	// 等待发牌
	WaitCard bool
	// 是否已看牌
	IsSeen bool
	// 是否已弃牌
	IsPacked bool
	// 是否已开牌
	IsShow bool
	// 是否已结算
	IsSettle bool
	// 是否已准备
	IsReady bool
	// 是否是庄家
	IsDealer bool
	// 是否获胜
	IsWin bool
	// 上一次操作
	LastOpt *msg.PlayerOpt
	// 是否可以亮牌
	CanShow bool
}

// 获取玩家ID
func (p *Player) GetUserId() string {
	return p.Id
}

func (r *Room) AddPlayer(p *Player) {
	r.Players = append(r.Players, p)
}

func (r *Room) RemovePlayer(p *Player) {
	for i, player := range r.Players {
		if player.Id == p.Id {
			r.Players = append(r.Players[:i], r.Players[i+1:]...)
			break
		}
	}
}

func (r *Room) RemoveAllRobot() {
	newPlayers := make([]*Player, 0)
	for _, player := range r.Players {
		if !player.IsRobot {
			newPlayers = append(newPlayers, player)
		}
	}
	r.Players = newPlayers
}

func (r *Room) GetPlayer(id string) *Player {
	for _, player := range r.Players {
		if player.Id == id {
			return player
		}
	}
	return nil
}

// 获取庄家的玩家
func (r *Room) GetDealerPlayer() *Player {
	for _, player := range r.Players {
		if player.IsDealer {
			return player
		}
	}
	return nil
}

// 设置指定玩家为庄家，并设置其他玩家为非庄家
func (r *Room) SetDealerPlayer(p *Player) {
	for _, player := range r.Players {
		player.IsDealer = false
	}
	p.IsDealer = true
}

// 获取WaitCard是false的所有玩家
func (r *Room) GetWaitCardPlayers() []*Player {
	players := make([]*Player, 0)
	for _, player := range r.Players {
		if !player.WaitCard {
			players = append(players, player)
		}
	}
	return players
}

// sitPos 是当前玩家的座位号，GetWaitCardPlayers  从sitPos开始 顺时针方向把所有玩家返回
// 从指定座位号开始顺时针获取所有玩家
func (room *Room) GetPlayersBySitPos(startSitPos int32) []*Player {
	players := make([]*Player, 0)
	maxSitPos := int32(5) //
	log.Debug("startSitPos:%v", room.Players)
	// 先添加大于等于 startSitPos 的座位
	for sitPos := startSitPos; sitPos <= maxSitPos; sitPos++ {
		for _, player := range room.Players {
			if player.SitPos == sitPos {
				players = append(players, player)
				break
			}
		}
	}

	// 再添加小于 startSitPos 的座位
	for sitPos := int32(0); sitPos < startSitPos; sitPos++ {
		for _, player := range room.Players {
			if player.SitPos == sitPos {
				players = append(players, player)
				break
			}
		}
	}

	return players
}

// 根据座位号获取玩家
func (r *Room) GetPlayerBySitPos(sitPos int32) *Player {
	// 查找对应座位号的玩家
	for _, player := range r.Players {
		if player.SitPos == sitPos {
			log.Debug("Player found: SitPos: %d, UserId: %s", player.SitPos, player.Id)
			return player
		}
	}
	// 如果没有找到玩家，记录日志并返回 nil
	log.Debug("Player with SitPos %d not found in room.", sitPos)
	return nil
}

// 增加玩家操作到当前回合
func (r *Room) AddPlayerOpt(round *msg.ReqRound) {
	r.Round++
	r.GameRound.Rounds = append(r.GameRound.Rounds, round)
}

// 设置当前回合为下个没有弃牌的玩家（顺时针）
func (r *Room) SetNextRound() {
	curSitPos := int32(r.RoundSitPos)

	player := r.GetPlayerBySitPos(curSitPos)
	player.CanShow = true
	// 按照座位号从小到大排序
	sort.Slice(r.Players, func(i, j int) bool {
		return r.Players[i].SitPos < r.Players[j].SitPos
	})
	count := len(r.Players)
	log.Debug("总人数count", count)
	// 获取当前座位号的索引
	curSitPosIndex := -1
	for i, player := range r.Players {
		if player.SitPos == curSitPos {
			curSitPosIndex = i
			break
		}
	}

	// 顺时针：当前索引加1
	// 如果加1后超出最大索引，则回到第一个位置
	nextIndex := curSitPosIndex
	for i := 0; i < len(r.Players); i++ {
		nextIndex = (curSitPosIndex + 1 + i) % len(r.Players)
		if !r.Players[nextIndex].IsPacked {
			break
		}
	}
	r.RoundSitPos = int(r.Players[nextIndex].SitPos)
	log.Debug("SetNextRound: 下一个操作的玩家座位：%d", r.RoundSitPos)
}

// 获取没有弃牌的玩家是否只有一个,并返回没有弃牌的座位号
func (r *Room) IsOnlyOneNotPacked() (bool, int32) {
	count := 0
	sitPos := int32(0)
	for _, player := range r.Players {
		if !player.IsPacked {
			count++
			sitPos = player.SitPos
		}
	}
	return count == 1, sitPos
}

// 当前座位号玩家获胜
func (r *Room) PlayerWin(sitPos int32) {
	player := r.GetPlayerBySitPos(sitPos)
	player.IsWin = true
	r.Status = RoomStatusEnd
}

func (r *Room) UpdateResBet(bet int32, chaalLimmit int32) {
	// 获取当前状态,是否修改
	if bet*2 < chaalLimmit {
		// 动态修改下注金额
		r.GameRound.ResBet.MinBlindBet = bet
		r.GameRound.ResBet.MaxBlindBet = bet * 2
		r.GameRound.ResBet.MinCheelBet = bet * 2
		r.GameRound.ResBet.MaxCheelBet = bet * 2
	} else if bet*4 < chaalLimmit {
		r.GameRound.ResBet.MaxCheelBet = bet * 4
	}

}

// 增加押注
func (r *Room) AddBet(bet int32) {
	r.GameRound.TotalBet += bet

}
