class_name TimeEntriesItemsTree extends Tree

enum COL{
	TEXT,
	TIME
}

var config: ConfigManager = preload("res://config_manager.tres")

var _timer := Timer.new()


func _ready() -> void:
	hide_root = true
	add_child(_timer)
	# warning-ignore:return_value_discarded
	connect("button_pressed", self, "_on_button_pressed")
	# warning-ignore:return_value_discarded
	_timer.connect("timeout", self, "_on_timer_timeout")
	# warning-ignore:return_value_discarded
	config.connect("time_sheet_loaded", self, "populate_entries")
	populate_entries()


func populate_entries() -> void:
	clear()
	var tree_items_root := create_item()
	var item_entries_tree := config.timesheet.make_items_tree()
	_populate_from_entry(tree_items_root, item_entries_tree)
	_timer.start()


func _on_timer_timeout() -> void:
	config.timesheet.update()


func _populate_from_entry(tree_item_root: TreeItem, time_entry_item_root: TimeEntryTreeItem):
	var children := time_entry_item_root.children
	for time_entry_name in children:
		var time_entry_item: TimeEntryTreeItem = children[time_entry_name]
		var item := find_or_create_item(tree_item_root, time_entry_name)
		item.set_metadata(COL.TEXT, time_entry_name)
		item.set_text(COL.TIME, time_entry_item.get_period())
		# warning-ignore:return_value_discarded
		time_entry_item.connect("end_time_updated", self, "_on_time_entry_changed_update_item", [time_entry_item, item])
		_populate_from_entry(item, time_entry_item)
		var has_at_least_one_running_entry := time_entry_item.find_active_time_entry() != null
		var texture := preload("res://assets/stop_small.svg") \
			if has_at_least_one_running_entry \
			else preload("res://assets/play_small.svg")
		item.add_button(COL.TIME, texture)
	var entries = time_entry_item_root.time_entries
	for entry_item in entries:
		var time_entry_item := entry_item as TimeEntryTreeItem
		var item := create_item(tree_item_root)
		var time_entry := time_entry_item.time_entry
		item.set_text(COL.TEXT, time_entry.start_time.to_string())
		item.set_metadata(COL.TEXT, time_entry_item.time_entry.name)
		item.set_text(COL.TIME, time_entry_item.get_period())
		if time_entry.is_closed == false:
			var texture := preload("res://assets/stop_small.svg")
			item.add_button(COL.TIME, texture)
		# warning-ignore:return_value_discarded
		time_entry_item.connect("end_time_updated", self, "_on_time_entry_changed_update_item", [time_entry_item, item])


func _on_time_entry_changed_update_item(time_entry_item: TimeEntryTreeItem, item: TreeItem) -> void:
	item.set_text(COL.TIME, time_entry_item.get_period())


func _on_button_pressed(item: TreeItem, _column: int, _id: int) -> void:
	var task_name: String = item.get_metadata(COL.TEXT)
	if task_name == "":
		return
	config.timesheet.toggle_entry(task_name)


## Unecessary in Godot 4, can bre replaced with get_children()
static func _get_tree_item_children(item: TreeItem):
	var children = []
	var child = item.get_children()
	if child == null:
		return children
	children.append(child)
	child = child.get_next()
	while child != null:
		children.append(child)
		child = child.get_next()
	return children


## Finds an item in the tree by text
func find_item(root: TreeItem, item_name: String) -> TreeItem:
	for child in _get_tree_item_children(root):
		if child.get_text(COL.TEXT) == item_name:
			return child
	return null


func find_or_create_item(root: TreeItem, item_name: String) -> TreeItem:
	var child := find_item(root, item_name)
	if child != null:
		return child
	child = create_item(root)
	child.set_text(COL.TEXT, item_name)
	return child
