extends Node


const MAX_PLAYERS: int = 10
const PORT: int = 7777

signal lobby_created
signal lobby_joined
signal lobby_closed
signal update_teams_state

var in_lobby: bool = false

var attack_team: Array[int] = []
var defence_team: Array[int] = []
var specators_team: Array[int] = []

var win_score = 13
var half_rounds = 12

func _ready() -> void:
	multiplayer.peer_disconnected.connect(player_left)
	multiplayer.server_disconnected.connect(server_disconnected)
	multiplayer.peer_connected.connect(add_and_sync_peer)

func player_left(id: int) -> void:
	if attack_team.has(id):
		attack_team.erase(id)
	elif defence_team.has(id):
		defence_team.erase(id)
	elif specators_team.has(id):
		specators_team.erase(id)
	update_teams_state.emit()

func server_disconnected() -> void:
	leave()

func host() -> void:
	var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new()
	peer.create_server(PORT,MAX_PLAYERS)
	multiplayer.multiplayer_peer = peer
	lobby_created.emit()
	specators_team.append(multiplayer.get_unique_id())
	in_lobby = true

func join(ip: String) -> Error:
	var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new()
	var res = peer.create_client(ip,PORT) 
	if res != 0:
		return res
	multiplayer.multiplayer_peer = peer
	lobby_joined.emit()
	in_lobby = true
	return Error.OK

func leave() -> void:
	multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new()
	attack_team.clear()
	defence_team.clear()
	specators_team.clear()
	lobby_closed.emit()
	in_lobby = false

func add_and_sync_peer(id: int) -> void:
	if multiplayer.is_server() == false:
		return
	specators_team.append(id)
	update_teams_state.emit()
	set_teams.rpc_id(id,attack_team,defence_team,specators_team)
	
@rpc("any_peer","call_remote","reliable")
func set_teams(attack: Array[int],defence: Array[int],spectators: Array[int]):
	attack_team = attack
	defence_team = defence
	specators_team = spectators
	update_teams_state.emit()

func switch_team(team: int) -> void:
	team_switch_notification.rpc(multiplayer.get_unique_id(),team)

@rpc("any_peer","call_local","reliable")
func team_switch_notification(id: int, team: int) -> void:
	if (team == Session.TEAMS.DEFENCE and len(defence_team) > 4) or (team == Session.TEAMS.ATTACK and len(attack_team) > 4):
		return
	if team == Session.TEAMS.DEFENCE:
		if attack_team.has(id):
			attack_team.erase(id)
		if specators_team.has(id):
			specators_team.erase(id)
		defence_team.append(id)
	
	if team == Session.TEAMS.ATTACK:
		if defence_team.has(id):
			defence_team.erase(id)
		if specators_team.has(id):
			specators_team.erase(id)
		attack_team.append(id)
	
	if team == Session.TEAMS.SPECTATE:
		if attack_team.has(id):
			attack_team.erase(id)
		elif defence_team.has(id):
			defence_team.erase(id)
		specators_team.append(id)
		
	update_teams_state.emit()

@rpc("authority","call_local","reliable")
func start_game() -> void:
	get_tree().change_scene_to_file("res://levels/prototype_scene.tscn")
	if multiplayer.is_server():
		await get_tree().scene_changed
		Session.start_session()

func get_team() -> Session.TEAMS:
	var id = multiplayer.get_unique_id()
	if attack_team.has(id):
		return Session.TEAMS.ATTACK
	if defence_team.has(id):
		return Session.TEAMS.DEFENCE
	if specators_team.has(id):
		return Session.TEAMS.SPECTATE
	return Session.TEAMS.UNASSIGNED
