class_name Level extends Node3D

const pawn_controller = preload("res://templates/pawn_controller.tscn")
const trap_template = preload("res://templates/trap.tscn")
const camera_template = preload("res://templates/pawn_camera.tscn")

const camera_offset = Vector3(0, 10, 5.25)


@onready var floor_layer : GridMap = %Floor
@onready var ramp_layer : GridMap = %Ramps
@onready var marker_layer : GridMap = %Markers
@onready var pawns_node : Node3D = %Pawns
@onready var traps_node : Node3D = %Traps
@onready var cameras_node : Node3D = %Cameras
@export var difficulty : int = 1

var traps : Dictionary[Vector3i, Trap] = {}
var pawns : Dictionary[int, PawnController] = {}
var cameras : Dictionary[int, PawnCamera] = {}
func _ready() -> void:
	Game.level = self

func setup() -> void:
	if Multiplayer.is_host():
		spawn_players()

func spawn_players() -> void:
	for key in Game.pawns_selected:
		var pc : PawnController = pawn_controller.instantiate()
		var pd = Game.pawns_selected[key]
		pawns_node.add_child(pc,true)
		var traps : Array = []
		for trap : TrapSet in pd.starting_traps:
			var dict = {
				"type":trap.type,
				"qty":trap.qty
			}
			traps.append(dict)
		
		var position : Vector3
		if key == Multiplayer.id:
			position = Vector3(0,0,0)
		else:
			position = Vector3(3,0,0)
		
		pc.setup.rpc(key,traps,position)
		add_pawn_camera(pc)
		

func is_square_detected(crd) -> bool:
	return marker_layer.get_cell_item(crd + Vector3i(0,-1,0)) != GridMap.INVALID_CELL_ITEM

func detect_square(crd : Vector3i, mark : bool) -> bool:
	var cell = floor_layer.get_cell_item(crd)
	if cell == GridMap.INVALID_CELL_ITEM:
		return false
	
	marker_layer.set_cell_item(crd, 0 if mark else GridMap.INVALID_CELL_ITEM)
	if mark:
		var trap_crd = crd + Vector3i(0,1,0)
		if traps.has(trap_crd):
			var trap : Trap = traps[trap_crd]
			if trap.trap_owner != Multiplayer.id:
				trap.reveal()
	return true

@rpc("any_peer", "call_local", "reliable")
func add_pawn_camera(pawn : PawnController) -> void:
	if Multiplayer.is_host():
		var camera : PawnCamera = camera_template.instantiate()
		camera.position = pawn.global_position + camera_offset
		cameras_node.add_child(camera,true)
		camera.register_pawn.rpc(pawn.id)
		


func add_trap(trap : Trap, crd : Vector3i) -> void:
	trap.square = crd
	traps[crd] = trap
	trap.position = Vector3(crd) + Vector3(.5, 0, .5)
	add_child(trap, true)

func add_projectile(shot : Projectile) -> void:
	add_child(shot, true)
	
func remove_trap_square(crd : Vector3i) -> void:
	traps.erase(crd)

func get_square_trap(crd : Vector3i) -> Trap:
	if traps.has(crd):
		return traps[crd]
	else:
		return null



func is_valid_trap_square(crd : Vector3i) -> bool:
	if floor_layer.get_cell_item(crd + Vector3i(0,-1,0)) == GridMap.INVALID_CELL_ITEM:
		return false
	if traps.has(crd):
		return false
	return true

func add_vfx(vfx, crd : Vector3i) -> void:
	vfx.position = Vector3(crd) #+ Vector3(0.5, 0, 0.5)
	add_child(vfx, true)
	
func activate_trap(crd : Vector3i) -> void:
	if traps.has(crd):
		traps[crd].activate()
		

func generate_trap(type : Trap.Type, dir : Vector3, square : Vector3i):
	var trap = trap_template.instantiate()
	trap.setup(type, dir, -1)
	add_trap(trap, square)

func disarm_trap(crd : Vector3i) -> void:
	var trap = traps[crd]
	trap.disarm()
	traps.erase(crd)
