package teen

import (
	"fmt"
	"math/rand"
	"server/common"
	redismgr "server/db/redis"
	"server/events"
	"server/game"
	"server/game/room"
	"server/msg"
	"server/user"
	"strconv"
	"time"

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

func MatchTeenPattiRoom(event events.Event) *room.Room {
	// 从事件中解析消息数据

	userData := event.Agent.UserData().(*common.UserData)
	RoomId := userData.Room_id // 默认房间ID是0 , 离开房间的时候需要重置为”0“

	m := event.Data.(*msg.ResJoinRoom)
	// 检查房间是否存在
	r := getRoomInfo(RoomId)
	// 房间不存在的情况
	if r == nil {
		log.Debug("Room %s does not exist, creating a new room or finding available room.", RoomId)
		// 在这里可以加入创建新房间或选择符合条件的房间的逻辑
		// 例如：创建一个新房间
		teenPattiRoom := createRoom(m.ConfId)

		// 返回创建的房间指针
		return teenPattiRoom
		// 返回创建的房间
	}
	// 房间存在的情况
	log.Debug("Room %s exists. Proceeding with user join.", RoomId)

	// 返回获取到的房间
	return r

}
func handleJoinTeenPattiRoom(event events.Event) {
	m := event.Data.(*msg.ResJoinRoom)
	// 匹配房间, 没有就建一个
	r := MatchTeenPattiRoom(event)
	// 判断是否符合加入条件
	isTrue := canJoinRoom(m.ConfId, event.Agent)
	// 如果条件不符合，返回房间创建失败信息，并终止后续代码执行
	if !isTrue {
		log.Debug("Room creation failed, returning RoomId: 0")
		// 发送失败的房间信息返回给客户端
		event.Agent.WriteMsg(&msg.JoinRoomFail{
			GameId: m.GameId,
			ConfId: m.ConfId,
			UserId: m.UserId,
		})
		return
	}
	userData := event.Agent.UserData().(*common.UserData)
	log.Debug("Room created with ID: %v", r.Id)

	// 玩家加入房间
	joinRoomAsPlayer(userData, event.Agent, r)

	// 判断房间人数，如果小于2个，加入机器人
	PlayerCount := len(r.Players)
	if PlayerCount < 2 {
		// random := rand.Intn(3) + 1
		random := 1
		for i := 0; i < random; i++ {
			joinRoomAsRobot(r)
		}
		// 设置下一个庄家
		setNextDealerSitPos(r, 1)
	}

	// 向每个玩家发送当前回合的信息
	for _, player := range r.Players {
		if player.Agent != nil {
			player.Agent.WriteMsg(&msg.ReqJoinRoom{
				UserId:   player.Id,
				RoomId:   r.Id,
				GameId:   "teen_patti",
				RoomInfo: buildRoom(r),
				SitPos:   player.SitPos,
			})
			log.Debug("Sent current round info to player %v in room %v", player.Id, r.Id)
		}
	}

	// 如果房间状态为等待状态（RoomStatusWaiting），则2秒后开始发牌
	if r.Status == 0 {
		game.Module.Skeleton.AfterFunc(time.Second*2, func() {
			go startDealCard(r)
		})
	}
	log.Debug("EventJoinTeenPattiRoom")
}
func buildRoom(teenPattiRoom *room.Room) *msg.ReqRoom {
	log.Debug("teenPattiRoom11111111111111111: %+v", teenPattiRoom)
	log.Debug("After creating room, ResBet: %+v", teenPattiRoom.GameRound.ResBet)
	return &msg.ReqRoom{
		Id:         teenPattiRoom.Id,
		Status:     int32(teenPattiRoom.Status),
		Round:      int32(teenPattiRoom.Round),
		ReqPlayers: convertToMsgPlayerList(teenPattiRoom.Players),
		GameRound:  convertToMsgGameRound(teenPattiRoom.GameRound),
		BetInfo:    teenPattiRoom.GameRound.ResBet,
	}
}

func convertToMsgPlayerList(players []*room.Player) []*msg.ReqPlayer {
	msgPlayers := make([]*msg.ReqPlayer, len(players))
	for i, player := range players {
		nickname := GetNickname(player)
		avatar := GetAvatar(player)
		log.Debug("nickname: %s", nickname)
		log.Debug("avatar: %s", avatar)
		msgPlayers[i] = &msg.ReqPlayer{
			Id: player.Id,
			// HandCards: convertToMsgCardList(player.HandCards),
			SitPos:   &player.SitPos,
			IsDealer: &player.IsDealer,
			IsSeen:   &player.IsSeen,
			IsPacked: &player.IsPacked,
			IsShow:   &player.IsShow,
			CanShow:  &player.CanShow,
			Nickname: &nickname,
			Avatar:   &avatar,
		}
	}
	return msgPlayers
}

func convertToMsgCardList(cards []*msg.ReqCard) []*msg.ReqCard {
	return cards
}

func convertToMsgGameRound(gameRound *room.GameRound) *msg.ReqGameRound {
	log.Debug("convertToMsgGameRound: %v", gameRound)
	return &msg.ReqGameRound{
		Rounds: convertToMsgRoundList(gameRound.Rounds),
	}
}
func convertToMsgRoundList(rounds []*msg.ReqRound) []*msg.ReqRound {
	return rounds
}

func convertToMsgRoomList(rooms []TeenPattiRoom) *msg.TeenPattiRoomList {
	msgRooms := make([]*msg.TeenPattiRoom, len(rooms))
	for i, room := range rooms {
		msgRooms[i] = &msg.TeenPattiRoom{
			Boot:         room.Boot,
			MinBuyin:     room.MinBuyin,
			ChaalLimmit:  room.ChaalLimmit,
			PotLimit:     room.PotLimit,
			TotalPlayers: room.TotalPlayers,
			RoomLevel:    room.RoomLevel,
			ConfId:       room.ConfId,
			Type:         room.Type,
		}
	}
	return &msg.TeenPattiRoomList{
		TeenPattiRoom: msgRooms,
	}
}

// 判断用户是否符合房间条件
func canJoinRoom(ConfId string, agent gate.Agent) bool {
	// 查找匹配的房间
	userData := agent.UserData().(*common.UserData)
	userData = user.GetUserInfoById(userData.Id)
	for _, room := range GameConfig.RoomList {
		if room.ConfId == ConfId {
			// 获取房间的最低买入金额
			minBuyin := room.MinBuyin
			minBuyinInt, err := strconv.Atoi(minBuyin)
			if err != nil {
				log.Error("Invalid minBuyin value: %v", minBuyin)
			}
			// 判断用户的余额是否满足最低买入金额
			if userData.Points < int32(minBuyinInt) {
				log.Debug("User %s does not have enough balance. Required: %d, Available: %d\n", userData.Id, minBuyin, userData.Points)
				agent.WriteMsg(&msg.ReqInsufficientPoints{
					UserId:          userData.Id,
					RequiredAmount:  int32(minBuyinInt),
					AvailableAmount: userData.Points,
					GameId:          "teen_patti",
				})
			}
			// 如果符合条件，返回 true
			return true
		}
	}

	// 如果没有找到匹配的房间
	log.Debug("Room not found with ID:", ConfId)
	return false
}
func generateRoomId() string {
	return fmt.Sprintf("room_%d", time.Now().UnixNano())
}
func loadTeemConf(ConfId string) *msg.ResBet {
	for _, betinfo := range GameConfig.RoomList {
		if betinfo.ConfId == ConfId {
			// 找到对应的房间配置
			Boot, err := strconv.Atoi(betinfo.Boot)
			if err != nil {
				log.Fatal("Error converting Boot:", err)
			}
			// 构造并返回 ResBet
			return &msg.ResBet{
				MinBlindBet: int32(Boot),
				MaxBlindBet: int32(Boot * 2),
				MinCheelBet: int32(Boot),
				MaxCheelBet: int32(Boot * 2),
				RoomMinBet:  int32(Boot),
				RoomMaxBet:  int32(Boot * 128),
			}
		}
	}
	return &msg.ResBet{
		MinBlindBet: 10,
		MaxBlindBet: 20,
		MinCheelBet: 10,
		MaxCheelBet: 20,
		RoomMinBet:  1,
		RoomMaxBet:  128,
	}
}
func createRoom(ConfId string) *room.Room {

	roomId := generateRoomId() // 生成房间 ID
	confInfo := loadTeemConf(ConfId)
	room := &room.Room{
		Id:      roomId,
		Status:  room.RoomStatusWaiting,
		Round:   1,
		Players: make([]*room.Player, 0),
		ConfId:  ConfId,
		GameRound: &room.GameRound{
			Rounds:   make([]*msg.ReqRound, 0),
			TotalBet: 0,
			ResBet:   confInfo,
		},
		CardDeck: make([]*msg.ReqCard, 0),
	}

	mu.Lock()
	log.Debug("创建roomid", roomId)
	roomStorage[roomId] = room
	mu.Unlock()
	return room
}

func dissolveRoom(teenPattiRoom *room.Room) {
	if teenPattiRoom == nil {
		return
	}

	log.Debug("Dissolving room %s", teenPattiRoom.Id)

	// 移除所有机器人
	for _, player := range teenPattiRoom.Players {
		if player.IsRobot {
			// 机器人退出房间，重置 Room_id
			redismgr.ResetRobotRoomID(player.Id)
			// 将机器人放回 Redis 空闲队列
			redismgr.AddRobotToFreeQueue(teenPattiRoom.ConfId, player.Id)
			log.Debug("Removed robot %s from room %s", player.Id, teenPattiRoom.Id)
		}
	}

	// 释放房间资源
	mu.Lock()
	delete(roomStorage, teenPattiRoom.Id)
	mu.Unlock()

	log.Debug("Room %s has been dissolved", teenPattiRoom.Id)
}

func getRoomInfo(roomId string) *room.Room {
	// 查找房间是否存在于内存中的 roomStorage
	room, exists := roomStorage[roomId]
	if !exists {
		return nil
	}
	return room
}

// 处理机器人加入房间
func joinRoomAsRobot(teenPattiRoom *room.Room) {
	randomSitPos := getRandomSitPos(teenPattiRoom) // 随机选择一个座位

	// 获取或创建新的机器人
	robotUserData, err := getOrCreateTeenPattiRobot(teenPattiRoom)
	if err != nil {
		log.Debug("Error getting or creating robot: %v", err)
		return
	}

	// 将机器人加入房间
	teenPattiRoom.Players = append(teenPattiRoom.Players, &room.Player{
		Id:        robotUserData.Id, // 使用时间戳生成机器人ID
		Agent:     nil,              // 机器人没有 agent
		IsRobot:   true,
		UserData:  robotUserData,
		SitPos:    randomSitPos,
		IsPacked:  false,
		IsSeen:    false,
		IsShow:    false,
		IsDealer:  false,
		CanShow:   false,
		HandCards: []*msg.ReqCard{},
	})

}

// 离开房间
func LeaveTeenPattiRoom(teenPattiRoom *room.Room, userId string, leaveReason string) {
	for i, player := range teenPattiRoom.Players {
		if player.Id == userId {
			log.Debug("Player %s left room %s", userId, teenPattiRoom.Id)
			player.Agent.SetUserData(&common.UserData{
				GameId: "",
			})

			// 发送离开消息
			if player.Agent != nil {
				player.Agent.WriteMsg(&msg.ReqLeaveRoom{
					GameId:      "teen_patti",
					RoomId:      teenPattiRoom.Id,
					UserId:      player.Id,
					LeaveReason: leaveReason,
				})
			}
			// 清除用户的房间 ID
			if userData, ok := player.Agent.UserData().(*common.UserData); ok && userData != nil {
				userData.Room_id = ""
			}
			// 从房间玩家列表中移除该玩家
			teenPattiRoom.Players = append(teenPattiRoom.Players[:i], teenPattiRoom.Players[i+1:]...)
			return // 退出循环，确保只删除一个玩家
		}
	}

	log.Debug("Player %s not found in room %s", userId, teenPattiRoom.Id)
}

// 处理玩家加入房间
func joinRoomAsPlayer(userData *common.UserData, agent gate.Agent, teenPattiRoom *room.Room) {
	// 将玩家加入房间
	// randomSitPos := getRandomSitPos(teenPattiRoom) // 随机选择一个座位

	teenPattiRoom.Players = append(teenPattiRoom.Players, &room.Player{
		Id:       userData.Id, // 使用玩家的 UserId
		Agent:    agent,
		IsRobot:  false,
		UserData: userData,
		SitPos:   4, // 你可以根据座位分配逻辑来设置
		// SitPos:    randomSitPos,
		IsPacked:  false,
		IsSeen:    false,
		IsShow:    false,
		IsDealer:  false,
		CanShow:   false,
		HandCards: []*msg.ReqCard{},
	})
	userData.Room_id = teenPattiRoom.Id
	user.SetUserInfo(userData)
	log.Debug("Player joined room")

	// 发送房间信息给所有玩家
	// sendCurrentRoundInfo(teenPattiRoom)
}

func getRandomSitPos(teenPattiRoom *room.Room) int32 {
	// 获取空闲的座位
	availableSitPos := getAvailableSitPos(teenPattiRoom)
	// 如果没有空座位，不能再加入机器人
	if len(availableSitPos) == 0 {
		log.Debug("No available seats for new robot in room %v", teenPattiRoom.Id)
		return 999
	}
	// 初始化随机数生成器
	random := rand.New(rand.NewSource(time.Now().UnixNano()))
	// 随机选择一个座位
	randomIndex := random.Intn(len(availableSitPos))
	selectedSitPos := availableSitPos[randomIndex]
	return selectedSitPos
}
