extends Node


signal level_map_updated()
signal game_started()
signal game_ended()
signal game_won()


var Levels = [
	"Level_0001",
	"Level_0002",
	"Level_0003",
	"Level_0004",
	"Level_0005",
	"Level_0005",
	"Level_0004",
	"Level_0002",
	"Level_0001",
]

var Level_Map = []


func _ready():
	Network.connect("game_started", self, "_on_Network_game_started")
	Network.connect("game_ended", self, "_on_Network_game_ended")
	
	self.init()


func init():
	randomize()
	self.Levels.shuffle()
	
	for level in self.Levels:
		self.Level_Map.push_back({
			time = 0,
			cleared_by = { # Network.player
				idx = -1,
				name = ""
			},
			meta = {
				path = "res://Levels/%s.tscn" % level,
				name = level,
			},
		})


func change_scene_to_instance(instance):
	call_deferred("_deferred_change_scene_to_instance", instance)
func _deferred_change_scene_to_instance(instance):
	get_tree().current_scene.free()
	get_tree().get_root().add_child(instance)
	get_tree().set_current_scene(instance)


func get_level(idx):
	return self.Level_Map[idx]


func get_instance_level(idx):
	var global_level = self.get_level(idx)
	
	var Level = load(global_level.meta.path)
	var instance_level = Level.instance()
	instance_level.idx = idx
	
	return instance_level


func start_level(idx):
	var instance_level = self.get_instance_level(idx)
	self.change_scene_to_instance(instance_level)


func end_level(instance_level):
	var global_level = self.get_level(instance_level.idx)
	
	var time = stepify(instance_level.timer, 0.01)
	if (global_level.time == 0 or time < global_level.time):
		global_level.time = time
		global_level.cleared_by = Network.player
	
	for id in Network.players:
		rpc_id(id, "_update_level_map", instance_level.idx, global_level)
	get_tree().change_scene("res://UI/LevelSelect.tscn")
	
	self.check_win()


func cancel_level():
	get_tree().change_scene("res://UI/LevelSelect.tscn")


remote func _update_level_map(idx, global_level):
	self.Level_Map[idx] = global_level
	emit_signal("level_map_updated")


func start_game():
	emit_signal("game_started")


func _on_Network_game_started():
	get_tree().change_scene("res://UI/CharacterSelect.tscn")


func end_game():
	emit_signal("game_ended")


func _on_Network_game_ended():
	get_tree().change_scene("res://UI/GameOver.tscn")
	self.Level_Map = []
	self.init()


func has_won():
	var has_won = false
	
	var cleared_levels_idx = []
	for idx in range(self.Level_Map.size()):
		if self.Level_Map[idx].cleared_by.idx == Network.player.idx:
			cleared_levels_idx.push_back(idx)
	
	var possible_winning_conditions = [
		[0, 1, 2],
		[3, 4, 5],
		[6, 7, 8],
		
		[0, 3, 6],
		[1, 4, 7],
		[2, 5, 8],
		
		[0, 4, 8],
		[2, 4, 6],
	]
	
	# because there's no intersection method on arrays..
	for cond in possible_winning_conditions:
		var has_cleared = 0
		for digit in cond:
			if digit in cleared_levels_idx:
				has_cleared += 1
		
		if has_cleared == 3:
			has_won = true
			break
	
	return has_won


func check_win():
	var has_won = self.has_won()
	
	if has_won:
		# TODO: start 10s timer with callback check_win_timer()
		# SAVE IN REMOTE ARRAY USERS WITH CROWN = rpc_id + running timer?
		# Check for each user that already has a crown if the win condition is still true
		# if it's not, delete user from array and stop timer
		# if it is, do nothing, keep running until game end
		self.check_win_timer()
		pass


func check_win_timer():
	var has_won = self.has_won()
	
	if has_won:
		emit_signal("game_won", Network.player)