extends HBoxContainer

class_name LogItem

#signal save(data:ItemData)
signal update(data: ItemData)
signal remove

const TAG_BTN_GROUP_PREFIX = "tag_btn"

@onready var log_content := %LogContent as TextEdit
@onready var event_date := %EventDate as Label
#@onready var update_date := %LogUpdateDate as Label
@onready var tags_container := %TagsContainer as GridContainer
@onready var add_tag_btn := %AddTag as MenuButton
@onready var reload_btn = %Reload
@onready var save_btn = %Save
@onready var delete_btn = %Delete

var original_data := ItemData.new()
var data: ItemData = original_data


class ItemData:
	var item_id := _generate_random_id()
	var log_content := "":
		set(new_val):
			if new_val != log_content:
				update_date = _get_current_time()
			log_content = new_val
	var tags := []:
		set(new_val):
			update_date = _get_current_time()
			tags = new_val
	var event_date := _get_current_time()
	var update_date := _get_current_time()

	func _generate_random_id() -> String:
		# float time
		var timestamp := Time.get_unix_time_from_system()
		return str(int(timestamp * 10000 + randi_range(0, 10000)))

	func _get_current_time() -> String:
		# Returns the current date as a dictionary of keys: year, month, day, and weekday.
		var dict = Time.get_date_dict_from_system()
		return str(dict["month"]) + "/" + str(dict["day"]) + "/" + str(dict["year"])

	func duplicate() -> ItemData:
		var item := ItemData.new()
		item.item_id = item_id
		item.log_content = log_content
		item.tags = tags.duplicate()
		item.event_date = event_date
		item.update_date = update_date
		return item

	func to_json_dict() -> Dictionary:
		# JSON.stringify(self) doesn't work
		return {
			"item_id": item_id,
			"log_content": log_content,
			"tags": tags,
			"event_date": event_date,
			"update_date": update_date,
		}

	static func parse(data: Dictionary) -> ItemData:
		var item := ItemData.new()
		if data.has("item_id"):
			item.item_id = data["item_id"]
		if data.has("tags"):
			item.tags = data["tags"]
		if data.has("log_content"):
			item.log_content = data["log_content"]
		if data.has("event_date"):
			item.event_date = data["event_date"]
		if data.has("update_date"):
			item.update_date = data["update_date"]
		return item


# {id:{"btn":btn,"key":key,"name":name,"id":id}}
static var tag_btns = {}
static var tag_key_to_id_map = {}

static var tag_shadow_color = Color.html("1b1b1b")
static var tag_shadow_outline_size = 1


# id->key
var current_tags = {}

func _ready():
	_load_tag_popup()
	reload_btn.pressed.connect(_on_reload_pressed)
	#save_btn.pressed.connect(_save_item)
	delete_btn.pressed.connect(_remove_signal)
	log_content.text_changed.connect(_on_log_content_changed)
	call_deferred("_update_signal")
	#load_item(original_data)


static func _static_init():
	var tag_id := 0
	for tag_type in ProjectLogPanel.TAG_TYPE.values():
		var tag_color = ProjectLogPanel.TAG_TYPE_COLOR_DICT[tag_type]
		for tag in ProjectLogPanel.TAG_DICT[tag_type]:
			var tag_btn = Button.new() as Button
			tag_btn.add_theme_color_override("font_color", tag_color)
			tag_btn.add_theme_color_override("font_shadow_color", tag_shadow_color)
			tag_btn.add_theme_constant_override("shadow_outline_size", tag_shadow_outline_size)
			tag_btn.text = tag
			var tag_key = _get_tag_key(tag_type, tag)
			tag_btns[tag_id] = {"btn": tag_btn, "id": tag_id, "name": tag, "key": tag_key}
			tag_key_to_id_map[tag_key] = tag_id
			tag_id += 1


static func _get_tag_key(tag_type: ProjectLogPanel.TAG_TYPE, tag: String):
	return str(tag_type) + "@" + tag


func _load_tag_popup():
	var popup = add_tag_btn.get_popup() as PopupMenu
	for btn_dict in tag_btns.values():
		popup.add_item(btn_dict["name"], btn_dict["id"])
	popup.id_pressed.connect(_on_popup_menu_pressed)


func _reload_tag_btns():
	var btn_group = TAG_BTN_GROUP_PREFIX + data.item_id
	get_tree().call_group(btn_group, "queue_free")
	current_tags.clear()
	for tag_key in data["tags"]:
		if !tag_key_to_id_map.has(tag_key):
			push_error("tag_key has been removed!! tag_key=", tag_key)
			continue
		var tag_id = tag_key_to_id_map[tag_key]
		current_tags[tag_id] = tag_key
		var btn = (tag_btns[tag_id]["btn"] as Button).duplicate()
		btn.pressed.connect(_on_tag_btn_pressed.bind(btn, tag_id))
		btn.add_to_group(btn_group)
		tags_container.add_child(btn)


func load_item(new_data: Dictionary):
	if new_data.keys().size() != 0:
		original_data = ItemData.parse(new_data)
	_reload_original_data()


func _reload_original_data():
	data = original_data.duplicate()
	#print("_load_item_data data=", data)
	log_content.text = data.log_content
	event_date.text = data.event_date
	#update_date.text = data["update_date"]
	_reload_tag_btns()


func _on_popup_menu_pressed(id: int):
	#{"btn":btn,"key":key,"name":name,"id":id}
	if !current_tags.has(id):
		current_tags[id] = tag_btns[id]["key"]
		data.tags = current_tags.values()
		_update_signal()
		#_save_item()
		_reload_tag_btns()


func _on_log_content_changed():
	data["log_content"] = log_content.text
	_update_signal()


func _on_tag_btn_pressed(btn: Control, id: int):
	current_tags.erase(id)
	btn.queue_free()
	data.tags = current_tags.values()
	_update_signal()
	#_save_item()


#func _save_item():
#save.emit(data)


func _update_signal():
	update.emit(data)


func _remove_signal():
	remove.emit()


func _on_reload_pressed():
	_reload_original_data()
	_update_signal()
