extends Node3D

class_name Actor

enum ACTOR_STATE {INACTIVE, ACTIVE, IDLE, PAUSED}

var actor_state = null: set = state_change

const red = preload("res://tiles/base_tile/red.tres")
const blue = preload("res://tiles/base_tile/lightblue.tres")

var current_task_path: Array
var current_room_path: Array

var current_tile = null: set = change_current_tile
var current_room = null

var lookup_actor_to_task :Array = []
var current_task: Dictionary : set = task_change

@onready var task_creator: TaskCreator = $TaskCreator

signal current_tile_request
signal task_path_request
signal room_path_request

func _process(delta: float) -> void:
	match actor_state:
		ACTOR_STATE.ACTIVE:
			get_current_tile()
			
			if current_tile.place_position == current_task.location:
				temp_complete_task()
			
			if current_task_path:
				if current_room_path:
					if self.position.distance_to(current_room_path[0]) > .1:
						position += position.direction_to(Vector3(current_room_path[0])) * 6 * delta
						DebugDraw3D.draw_line(self.position, current_room_path[0])
						for i in current_room_path.size():
							if i > 0:
								var j = current_room_path[i - 1]
								DebugDraw3D.draw_line(current_room_path[i], j)
					else:
						current_room_path.pop_front()
						if not current_room_path:
							current_task_path.pop_front()
				else:
					get_room_path(current_tile.place_position, current_task_path[0])
			else:
				get_task_path()
		ACTOR_STATE.IDLE:
				
			if not lookup_actor_to_task.is_empty():
				current_task = lookup_actor_to_task[0]
			else:
				actor_state = ACTOR_STATE.PAUSED
				
		ACTOR_STATE.PAUSED:
			pass

func state_change(state :int ) -> void:
	actor_state = state
	match state:
		ACTOR_STATE.ACTIVE:
			$SelfMesh.set_material_override(red)
		ACTOR_STATE.IDLE:
			$SelfMesh.set_material_override(null)
		ACTOR_STATE.PAUSED:
			$SelfMesh.set_material_override(blue)
			await get_tree().create_timer(1).timeout
			temp_create_task()
			actor_state = ACTOR_STATE.IDLE

func task_change(task):
	current_task = task
	if current_task:
		actor_state = ACTOR_STATE.ACTIVE
		get_task_path()

func get_current_tile():
#Requests the tile that this actor is currently on
	
	emit_signal("current_tile_request", self)

func change_current_tile(new_tile):
#General function for when this actor enters a new tile

	if current_tile != new_tile:
		current_tile = new_tile
		get_room()

func get_room():
#Gets the room that the current tile is in

	if current_tile.lookup_tile_to_room:
		current_room = current_tile.lookup_tile_to_room
	else:
		current_room = null

func temp_create_task():
	var temp_task_target = Vector3i(randi_range(1, 31), 0, randi_range(1, 31))
	task_creator.create_task(
		self,
		self,
		temp_task_target,
				)

func temp_complete_task():
	if lookup_actor_to_task:
		var completed_task = lookup_actor_to_task.pop_front()
		current_task = {}
		task_creator.complete_task(self, completed_task)
		actor_state = ACTOR_STATE.IDLE

func get_task_path() -> void:
	get_current_tile()
	var start :Vector3i = current_tile.place_position
	var end :Vector3i = current_task.location
	
	#if destination_in_current_room(end):
		#current_task_path = [start, end]
	#else:
		##temp_complete_task()
	emit_signal("task_path_request", self, start, end)

func get_room_path(start :Vector3i, end :Vector3i) -> void:
	emit_signal("room_path_request", self, start, end)
	#current_room_path = current_room.get_room_path(start, end)

func destination_in_current_room(destination):
	for i in current_room.room_to_tile:
		if i.place_position == destination:
			return true
	return false
