extends Node

@export var user_archive_root_dir := "user://archive/"  # must end with "/"
@export var save_dir_prefix := "save"

var accessible := false
var archives: Array[int]  # archive id list in ascending order

var managers = {
	"TimeManager": TimeManager,
	"EntityManager": EntityManager,
	"SceneManager": SceneManager,
	"InputManager": InputManager,
	# "ArchiveManager" : ArchiveManager, #self
	# "AudioManager" : AudioManager,
	# "EventManager" : EventManager,
	# "CameraManager" : CameraManager,
	# "DialogManager" : DialogManager,
	# "CgManager": CgManager,
}

var autosave_timer := Timer.new()

func _ready() -> void:
	accessible = _check_archive_dirs()
	if !accessible:
		return
	# _open_log_file()
	add_child(autosave_timer)
	autosave_timer.wait_time = GlobalConfigManager.config.auto_save_seconds
	autosave_timer.one_shot = false
	autosave_timer.timeout.connect(_try_auto_save)
	autosave_timer.stop()
	GlobalConfigManager.config.current_selected_save_changed.connect(_check_autosave_options)
	GlobalConfigManager.config.auto_save_seconds_changed.connect(_check_autosave_options)
	load_all()
	SceneManager.pop_notification("预加载完成")



func _check_autosave_options():
	if (
		GlobalConfigManager.config.auto_save_seconds > 5
		and GlobalConfigManager.config.current_selected_save >= 0
	):
		autosave_timer.start()
	else:
		autosave_timer.stop()


func _try_auto_save():
	if (
		GlobalConfigManager.config.auto_save_seconds > 5
		and GlobalConfigManager.config.current_selected_save >= 0
	):
		save_all()
		SceneManager.pop_notification("自动保存成功")


func _check_archive_dirs() -> bool:
	# Check if the archive directory is accessible
	if !DirAccess.dir_exists_absolute(user_archive_root_dir):
		DirAccess.make_dir_recursive_absolute(user_archive_root_dir)
		print("Create archive directory:", user_archive_root_dir)
	var archive_dir_access = DirAccess.open(user_archive_root_dir)
	if !archive_dir_access:
		printerr("Archive directory is not accessible")
		# TODO pop up a dialog to inform the user
		return false
	var files = archive_dir_access.get_files()
	# get archive number
	for file in files:
		if file.begins_with(save_dir_prefix):
			var id_str = file.substr(save_dir_prefix.length())
			var id = int(id_str)
			archives.append(id)
	archives.sort()
	return true


func save_all() -> void:
	# save config
	var config = GlobalConfigManager.config
	var path = user_archive_root_dir + "config" + GlobalConfig.RES_FILE_FORMAT
	ResourceSaver.save(config, path)
	if not accessible or GlobalConfigManager.config.current_selected_save == -1:
		return
	# Save all managers by the current selected save
	for manager in managers:
		# .tres
		var res = managers[manager].get_data_res()
		if !res:
			continue
		# save to file
		path = (
			user_archive_root_dir
			+ str(config.current_selected_save)
			+ "/"
			+ manager
			+ GlobalConfig.RES_FILE_FORMAT
		)
		ResourceSaver.save(res, path)


func load_all() -> void:
	_check_archive_dirs()
	# load config
	var path = user_archive_root_dir + "config" + GlobalConfig.RES_FILE_FORMAT
	var config
	if FileAccess.file_exists(path):
		config = ResourceLoader.load(path)
		GlobalConfigManager.load_data_res(config)
	else:
		config = GlobalConfigManager.config
		# save config
		ResourceSaver.save(config, path)
	if not accessible or config.current_selected_save == -1:
		return
	# Load managers by the current selected save
	path = user_archive_root_dir + save_dir_prefix + str(config.current_selected_save) + "/"
	for manager in managers:
		var manager_path = path + manager + GlobalConfig.RES_FILE_FORMAT
		if FileAccess.file_exists(manager_path):
			var res = ResourceLoader.load(manager_path)
			managers[manager].load_data_res(res)
