package teen

import (
	"fmt"
	"server/game"
	"server/game/room"
	"server/msg"
	"time"

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

// 创建定时管理器
var timerMgr = NewTimerManager()

// 开始发牌，先给庄家发牌
func startDealCard(r *room.Room) {
	initCardDeck(r)
	shuffleCardDeck(r.CardDeck)
	log.Debug("r.Status: %d", r.Status)
	if r.Status == room.RoomStatusWaiting {
		r.Status = room.RoomStatusDealing
		dealer := r.GetDealerPlayer()
		r.RoundSitPos = int(dealer.SitPos)

		players := r.GetPlayersBySitPos(dealer.SitPos)
		// 让所有玩家进行下底
		for _, player := range players {
			log.Debug("发牌时下底的用户: %d", player.SitPos)

			delay := time.Duration(300 * time.Millisecond)
			game.Module.Skeleton.AfterFunc(delay, func() {

				// ante(r, player.SitPos, 100)
				ante(r, player.SitPos, getAnte(r.ConfId))

			})
		}

		time.Sleep(time.Second * 2)

		//每个玩家从第一张开始发，发完再给每个玩家发第二张牌，发完再给每个玩家发第三张牌，要有序有间隔的体现
		log.Debug("发牌的房间id: %d", r.Id)

		for index := 0; index < 3; index++ {
			for i, player := range players {
				log.Debug("发牌用户: %d", player.SitPos)
				player.HandCards = getThreeCards(r)
				player.WaitCard = false
				// 计算延时：轮次*总延时 + 玩家索引*单次延时
				delay := time.Duration(index*len(players)+i) * 300 * time.Millisecond
				game.Module.Skeleton.AfterFunc(delay, func() {
					notifyPlayerDealCard(r, player.SitPos, int32(index))
				})
			}
		}

		game.Module.Skeleton.AfterFunc(time.Second*3, func() {
			notifyPlayerAction(r, dealer.SitPos, msg.PlayerOptType_OPT_SELECT)
			r.Status = room.RoomStatusPlaying
		})

	}
}

// 返回牌堆里3张牌,并从牌堆中移除
func getThreeCards(room *room.Room) []*msg.ReqCard {
	// 获取前三张牌
	threeCards := (room.CardDeck)[:3]
	// 移除这三张牌（保留剩余的牌）
	room.CardDeck = (room.CardDeck)[3:]
	// 返回这三张牌
	return threeCards
}

// 通知玩家发牌
func notifyPlayerDealCard(room *room.Room, sitPos int32, index int32) {
	//遍历所有玩家
	for _, player := range room.Players {
		if player.Agent != nil {
			player.Agent.WriteMsg(&msg.ReqDealCard{SitPos: &sitPos, Index: &index})
		}
	}
}

// 通知玩家操作
func notifyPlayerAction(room *room.Room, sitPos int32, optType msg.PlayerOptType) {
	player := room.GetPlayerBySitPos(sitPos)
	if !player.IsRobot {

	} else {
		//人机直接操作
		robotOpt(room, sitPos, optType)
	}
	log.Debug("通知玩家开始操作: %d", sitPos)

	players := room.GetPlayersBySitPos(sitPos)
	for _, p := range players {
		if p.Agent != nil {
			p.Agent.WriteMsg(&msg.ReqPlayerAction{
				SitPos:    int32(sitPos),
				PlayerOpt: &msg.PlayerOpt{OptType: optType},
				ResBet:    room.GameRound.ResBet,
			})
		}
		if sitPos == p.SitPos && !p.IsRobot {
			if optType == msg.PlayerOptType_OPT_SELECTSITESHOW {
				log.Debug("通知玩家开始操作2: %d", sitPos)

				addPlayerOptSiteShowTimeout(room, player, time.Second*time.Duration(GameConfig.ThinkTime))
				log.Debug("通知玩家开始操作3: %d", sitPos)

			} else {
				log.Debug("通知玩家开始操作4: %d", sitPos)

				addPlayerOptTimeout(room, player, time.Second*time.Duration(GameConfig.ThinkTime))
				log.Debug("通知玩家开始操作5: %d", sitPos)

			}
		}
	}
	log.Debug("通知玩家开始操作6: %d", sitPos)

	// game.Module.Skeleton.AfterFunc(time.Second*time.Duration(GameConfig.ThinkTime), func() {

	// })
}

// 添加玩家操作超时事件
func addPlayerOptTimeout(room *room.Room, player *room.Player, timeout time.Duration) {
	eventID := fmt.Sprintf("player_%s_opt_%s", player.Id, player.SitPos)
	timerMgr.AddEvent(eventID, timeout, func() {
		// 超时处理逻辑，弃牌
		// packed(room, player.SitPos)
		recvPlayerOptAction(room, player.SitPos, &msg.PlayerOpt{OptType: msg.PlayerOptType_OPT_PACKED})
		// show(room, player.SitPos)
	})
}

// 添加玩家操作超时事件
func addPlayerOptSiteShowTimeout(room *room.Room, player *room.Player, timeout time.Duration) {
	eventID := fmt.Sprintf("player_%s_opt_%s", player.Id, player.SitPos)
	timerMgr.AddEvent(eventID, timeout, func() {
		// 超时处理逻辑，弃牌
		// packed(room, player.SitPos)
		recvPlayerOptAction(room, player.SitPos, &msg.PlayerOpt{OptType: msg.PlayerOptType_OPT_REFUSESITESHOW})
	})
}

// 收到玩家操作
func recvPlayerOptAction(room *room.Room, sitPos int32, opt *msg.PlayerOpt) {
	player := room.GetPlayerBySitPos(sitPos)
	optType := opt.OptType
	sendRoomDynamicMsg(room, fmt.Sprintf("玩家%s选择了%s", GetNickname(player), optType.String()))
	// log.Debug("recvPlayerOptAction, optType:%v", optType)
	player.LastOpt = &msg.PlayerOpt{OptType: optType}
	if optType == msg.PlayerOptType_OPT_SEEN { // 看牌
		seen(room, sitPos)
	} else {
		cancelOptTimeout(player, sitPos)
		if optType == msg.PlayerOptType_OPT_PACKED { // 弃牌
			packed(room, sitPos)

		} else if optType == msg.PlayerOptType_OPT_BLIND { // 跟注
			blind(room, sitPos, opt.BetAmount)
		} else if optType == msg.PlayerOptType_OPT_CHAAL { // 跟注

			chaal(room, sitPos, opt.BetAmount)
		} else if optType == msg.PlayerOptType_OPT_SITESHOW { // 发起与上家比牌
			site_show(room, sitPos, opt.BetAmount)
		} else if optType == msg.PlayerOptType_OPT_REFUSESITESHOW { // 拒绝与下家比牌
			go RefuseSiteShow(room, sitPos)
		} else if optType == msg.PlayerOptType_OPT_AGREESITESHOW { // 同意与下家比牌
			go AgreeSiteShow(room, sitPos)
		} else if optType == msg.PlayerOptType_OPT_SHOW { // 亮牌
			go show(room, sitPos)
		}
	}
	updateAllPlayerInfo(room)
}
func SendUserInfoMsg(room *room.Room, mg *msg.ReqUserInfo) {
	for _, player := range room.Players {
		if player.Agent != nil && player.Id == mg.UserId {
			player.Agent.WriteMsg(mg)
		}
	}
}

// 发送消息给所有玩家
func SendRoundMsgToAll(room *room.Room, mg *msg.ReqRound) {
	if mg.PlayerOpt.OptType == msg.PlayerOptType_OPT_SEEN {
		if mg.RoundSitPos != SelfSitPos {
			mg.PlayerOpt.SeenCards = nil
		}
	}
	for _, player := range room.Players {
		if player.Agent != nil {
			player.Agent.WriteMsg(mg)
		}
	}
	room.AddPlayerOpt(mg)
}

// 更新所有玩家的操作
func updateAllPlayerInfo(room *room.Room) {
	for _, player := range room.Players {
		if player.Agent != nil {
			player.Agent.WriteMsg(&msg.ReqPlayerList{ReqPlayers: convertToMsgPlayerList(room.Players)})
		}
	}
}

// 发送房间押注
func sendRoomBet(room *room.Room) {
	for _, player := range room.Players {
		if player.Agent != nil {
			player.Agent.WriteMsg(&msg.ReqBet{BetAmount: &room.GameRound.TotalBet})
		}
	}
}

// 发送结果
func sendResult(r *room.Room, sitPos int32) {

	log.Debug("发送结果: %d", r.GameRound.TotalBet)
	for _, player := range r.Players {
		if player.Agent != nil {
			player.Agent.WriteMsg(&msg.ReqResult{RoundSitPos: &sitPos, Result: &r.GameRound.TotalBet})
		}
	}
}

// 发房间动态消息提示
func sendRoomDynamicMsg(r *room.Room, room_msg string) {
	log.Debug("sendRoomDynamicMsg: %s", room_msg)
	for _, player := range r.Players {
		if player.Agent != nil {
			player.Agent.WriteMsg(&msg.ReqRoomTipsMessage{Msg: room_msg})
		}
	}
}
