extends Node

const MAX_LEVEL_SIZE := 40
const MAX_LEVEL_HEIGHT := 30
const LEVEL_CHUNK_SIZE := 4
var chunks_xz
var chunks_y
var editor = null
var game = null

@onready var settings = $"/root/Settings"


const LIST_FILE_PATH := "user://known_levels_list.json"


const USER_PATH := "user://"

const LEVEL_EXTENSION := ".level.json"


var filesystem = preload("res://scripts/services/filesystem.gd").new()

var levels := {}
var editor_level_path
var binary_level_path = ""

var selected_level = ""
var exec_context = ""

#called whenever a level has been added, deleted*, renamed* or the level path has changed //  * = not yet implemented
#signal level_list_updated



func _ready() -> void:
	chunks_xz = ceil(MAX_LEVEL_SIZE / LEVEL_CHUNK_SIZE)
	chunks_y = ceil(MAX_LEVEL_HEIGHT / LEVEL_CHUNK_SIZE)
	
	
	var binary_dir = OS.get_executable_path().get_base_dir().replace("\\", "/")
	if !OS.has_feature("editor"):
		binary_level_path = binary_dir.path_join("levels/")
	editor_level_path = self.settings.get_option("editor_level_path")
	
	selected_level = self.settings.get_option("selected_level")
	load_levels_from_dir()
	

	
#func save_list_to_file() -> void:
#	self.filesystem.write_data_as_json_to_file(self.LIST_FILE_PATH, self.levels)

func load_levels_from_dir() -> void:
	#level_manager.binary_level_path
	#if OS.has_feature("editor"):
	levels.clear()
	var _levels = _load_level_names_from_dir(get_level_path())
	
	for _level_name in _levels:
		var lv_data = {"name": _level_name}
		levels[_level_name] = lv_data

#currently not in use, but can be used to load only certain levels from a list
func load_levels_from_list_file() -> void:
	self.levels = self.filesystem.read_json_from_file(self.LIST_FILE_PATH)

func _load_level_names_from_dir(dir_path) -> Array:
	var _levels
	var names = []
	
	print ("trying to load levels from dir: " + str(dir_path))
	_levels = filesystem.dir_files(dir_path, LEVEL_EXTENSION)
	
	if self.filesystem.dir_exists(dir_path):
		var file_list = _levels

		for file_name in file_list:
			
			if file_name.ends_with(self.LEVEL_EXTENSION) and file_name != "__autosave__.level.json":
				names.append(file_name.replace(self.LEVEL_EXTENSION, ""))
	else:
		print ("ERROR: dir to load doesn't exist: " + str(dir_path))

	return names

func get_levels_page(page_number: int, page_size: int) -> Array:
	var pages_count = self.get_pages_count(page_size)
	if page_number >= pages_count:
		return []

	var index_start := page_number * page_size 
	var index_end := index_start + page_size

	var level_key_list := []
	level_key_list = self.levels.keys()
	level_key_list.sort()

	var levels_count: int = level_key_list.size()
	if index_end > levels_count:
		index_end = levels_count

	var index = index_start
	var output := []

	while index < index_end:
		output.append(level_key_list[index])
		index += 1

	return output

func get_pages_count(page_size: int) -> int:
	var total_level_count := 0
	
	total_level_count = self.levels.size()


	var last_page_overflow := total_level_count % page_size
	@warning_ignore("integer_division")
	var pages_count := (total_level_count - last_page_overflow) / page_size

	if last_page_overflow > 0:
		pages_count += 1

	return pages_count

func level_exists(level_name: String) -> bool:

	var filepath = self.get_level_and_path(level_name)
	return self.filesystem.file_exists(filepath)

func get_level_data(level_name: String) -> Dictionary:
	var filepath := self.get_level_and_path(level_name)
	print (filepath)
	return self.filesystem.read_json_from_file(filepath)

func save_level_to_file(filename: String, content: Dictionary) -> void:
	var filepath = self.get_level_and_path(filename)
	self.filesystem.write_data_as_json_to_file(filepath, content)

func get_level_path() -> String:
	if OS.has_feature("editor"):
		return self.editor_level_path
	else:
		return self.binary_level_path

func get_level_and_path(level_name: String) -> String:
	
	if level_name != "__autosave__":
		return get_level_path() + level_name + self.LEVEL_EXTENSION
	else:
		return self._get_user_level_path(level_name)
	
func _get_user_level_path(level_name: String) -> String:
	return self.USER_PATH + level_name + self.LEVEL_EXTENSION


func get_level_details(level_key: String) -> Dictionary:
	return self.levels[level_key]

