extends Node
class_name CitizenManager

@export var task_assignment_rate: float = 100

var task_assignment_budget: float = 0
var task_queue: Array[Task] = []

static var _instance: CitizenManager = null

#signal task_queue_updated(task_queue: Array[Task])

func _init() -> void:
	if _instance == null:
		_instance = self
	else:
		assert(false, "A second CitizenManager was created you fucking moron")

func _process(delta: float) -> void:
	task_assignment_budget += task_assignment_rate * delta
	if task_assignment_budget >= task_assignment_rate:
		task_assignment_budget = task_assignment_rate
	
	var idle_workers: Array[Citizen] = []
	for worker in get_children():
		if worker is Citizen:
			if worker.is_idle():
				idle_workers.append(worker)
			
	#idle_workers.shuffle()
	
	while !idle_workers.is_empty() and !task_queue.is_empty() and task_assignment_budget >= 1:
		var task: Task = task_queue.pop_front()
		task_assignment_budget -= 1
		if task.is_ready_to_start():
			# TODO: this currently assigns to the first worker found
			var worker: Citizen = idle_workers.pop_front()
			worker.assign_task(task)
		else:
			add_task(task)

func remove_task(task: Task):
	var idx: int = task_queue.find(task)
	if idx >= 0:
		task_queue.remove_at(idx)

func add_task(task: Task):
	print("Task added to queue: %s" % task.get_task_name())
	var idx: int = task_queue.bsearch_custom(task, sort_tasks, false)
	task_queue.insert(idx, task)
	
func sort_tasks(a: Task,b: Task) -> bool:
	return a.priority > b.priority
	
const TASK_PRIORITY_ANYTIME = 0
const TASK_PRIORITY_BY_WAVE_START = 10
const TASK_PRIORITY_ASAP = 20