package game

import (
	"sync"
	"time"

	"github.com/wonderivan/logger"
)

type Room struct {
	//房间ID，目前没啥用，就是方便打印查看
	ID int
	//入房钥匙
	EnterKey string
	//玩家列表
	PlayerList []*Player
}

var staticRoomMapLocker sync.RWMutex
var staticRoomMap = make(map[string]*Room)

//进入房间
func EnterRoom(player *Player, enterKey string) {
	staticRoomMapLocker.Lock()
	defer staticRoomMapLocker.Unlock()
	needCreateRoom := false
	room := staticRoomMap[enterKey]
	if room == nil {
		needCreateRoom = true
	} else if room != nil {
		needCreateRoom = room.IsFullMembers()
	}
	if needCreateRoom {
		room = &Room{ID: GetUuidInt("Room"), EnterKey: enterKey, PlayerList: []*Player{player, nil}}
		go room.AutoCheck()
		staticRoomMap[enterKey] = room
		logger.Info("roomID:", room.ID, "Create", "EnterKey:", room.EnterKey)
		player.OnEnterRoom(room)
	} else {
		room.PlayerList[1] = player
		player.OnEnterRoom(room)
		room.OnRoomReadyComplete()
	}
}

//开启检测-主要为了自动销毁
func (room *Room) AutoCheck() {
	defer room.CloseAllPlayers()
	defer func() {
		staticRoomMapLocker.Lock()
		if staticRoomMap[room.EnterKey] == room {
			delete(staticRoomMap, room.EnterKey)
		}
		staticRoomMapLocker.Unlock()
		logger.Info("roomID:", room.ID, "Destroy")
	}()
	loopInterval := 2
	waitTime := 0
	for {
		time.Sleep(time.Duration(loopInterval) * time.Second)
		if room.IsFullMembers() {
			if !room.IsAllMembersValid() {
				break
			}
		} else {
			waitTime += loopInterval
			if waitTime >= 30 {
				break
			}
		}
	}
}

//判断房间的人数是否已满
func (room *Room) IsFullMembers() bool {
	for _, p := range room.PlayerList {
		if p == nil {
			return false
		}
	}
	return true
}

//判断房间内是由所有玩家都有效
func (room *Room) IsAllMembersValid() bool {
	for _, p := range room.PlayerList {
		if !p.IsValid {
			return false
		}
	}
	return true
}

//关闭所有玩家连接
func (room *Room) CloseAllPlayers() {
	for _, p := range room.PlayerList {
		if p != nil {
			p.Conn.Close()
		}
	}
}

//广播到其他人
func (room *Room) BroadcastToOthers(player *Player, func_ string, args ...interface{}) {
	for _, p := range room.PlayerList {
		if p != nil && p != player {
			SendPackFunction(p.Conn, func_, args...)
		}
	}
}

//广播到全部人
func (room *Room) BroadcastToAll(func_ string, args ...interface{}) {
	for _, p := range room.PlayerList {
		if p != nil {
			SendPackFunction(p.Conn, func_, args...)
		}
	}
}

//向客户端发送的请求
//房间准备完毕，即房间内的玩家都准备好了，接到该通知就可以开始游戏啦
func (room *Room) OnRoomReadyComplete() {
	for playerIndexInRoom, p := range room.PlayerList {
		SendPackFunction(p.Conn, "OnRoomReadyComplete", playerIndexInRoom)
	}
	logger.Info("roomID:", room.ID, "OnRoomReadyComplete")
}
