# Input map operations module
# Handles: setup_input_map_op, list_input_actions_op
# Corresponds to: test_input_tilemap_material.py (Input section)
class_name InputOps


## Setup input map action with key bindings
static func setup_input_map_op(ctx: SceneTree, params: Dictionary) -> void:
	var action_name: String = params.action_name
	var keys: Array = params.keys if params.has("keys") else []
	
	print("Setting up input map action: " + action_name)
	
	if ctx.debug_mode:
		print("Action name: " + action_name)
		print("Keys: " + str(keys))
	
	# The input map setting key in project.godot
	var input_setting_key: String = "input/" + action_name
	
	# Create the action configuration
	var action_config: Dictionary = {
		"deadzone": 0.5,
		"events": []
	}
	
	# Parse key strings and create InputEventKey resources
	for key_string in keys:
		var event: InputEventKey = _create_input_event_from_string(ctx, key_string)
		if event:
			action_config["events"].append(event)
			if ctx.debug_mode:
				print("Added key event: " + key_string)
		else:
			ctx.log_error("Failed to parse key: " + key_string)
	
	# Set the input action in ProjectSettings
	ProjectSettings.set_setting(input_setting_key, action_config)
	
	if ctx.debug_mode:
		print("Input action configured: " + input_setting_key)
	
	# Save the project settings
	var error: int = ProjectSettings.save()
	if ctx.debug_mode:
		print("Save result: " + str(error) + " (OK=" + str(OK) + ")")
	
	if error == OK:
		print("Input map action '" + action_name + "' set up successfully with keys: " + str(keys))
	else:
		printerr("Failed to save project settings: " + str(error))
		ctx.quit(1)


## Helper function to create InputEventKey from a key string
static func _create_input_event_from_string(ctx: SceneTree, key_string: String) -> InputEventKey:
	var event: InputEventKey = InputEventKey.new()
	
	# Parse modifier keys
	var parts: PackedStringArray = key_string.to_upper().split("+")
	var main_key: String = parts[-1].strip_edges()
	
	# Check for modifiers
	for i in range(parts.size() - 1):
		var modifier: String = parts[i].strip_edges()
		match modifier:
			"CTRL", "CONTROL":
				event.ctrl_pressed = true
			"ALT":
				event.alt_pressed = true
			"SHIFT":
				event.shift_pressed = true
			"META", "CMD", "COMMAND":
				event.meta_pressed = true
	
	# Map common key names to Key enum values
	var key_map: Dictionary = {
		# Letters
		"A": KEY_A, "B": KEY_B, "C": KEY_C, "D": KEY_D, "E": KEY_E,
		"F": KEY_F, "G": KEY_G, "H": KEY_H, "I": KEY_I, "J": KEY_J,
		"K": KEY_K, "L": KEY_L, "M": KEY_M, "N": KEY_N, "O": KEY_O,
		"P": KEY_P, "Q": KEY_Q, "R": KEY_R, "S": KEY_S, "T": KEY_T,
		"U": KEY_U, "V": KEY_V, "W": KEY_W, "X": KEY_X, "Y": KEY_Y, "Z": KEY_Z,
		# Numbers
		"0": KEY_0, "1": KEY_1, "2": KEY_2, "3": KEY_3, "4": KEY_4,
		"5": KEY_5, "6": KEY_6, "7": KEY_7, "8": KEY_8, "9": KEY_9,
		# Function keys
		"F1": KEY_F1, "F2": KEY_F2, "F3": KEY_F3, "F4": KEY_F4,
		"F5": KEY_F5, "F6": KEY_F6, "F7": KEY_F7, "F8": KEY_F8,
		"F9": KEY_F9, "F10": KEY_F10, "F11": KEY_F11, "F12": KEY_F12,
		# Special keys
		"SPACE": KEY_SPACE, "ENTER": KEY_ENTER, "RETURN": KEY_ENTER,
		"TAB": KEY_TAB, "ESCAPE": KEY_ESCAPE, "ESC": KEY_ESCAPE,
		"BACKSPACE": KEY_BACKSPACE, "DELETE": KEY_DELETE, "DEL": KEY_DELETE,
		"INSERT": KEY_INSERT, "HOME": KEY_HOME, "END": KEY_END,
		"PAGEUP": KEY_PAGEUP, "PAGEDOWN": KEY_PAGEDOWN,
		"UP": KEY_UP, "DOWN": KEY_DOWN, "LEFT": KEY_LEFT, "RIGHT": KEY_RIGHT,
		# Punctuation
		"MINUS": KEY_MINUS, "EQUAL": KEY_EQUAL, "EQUALS": KEY_EQUAL,
		"BRACKETLEFT": KEY_BRACKETLEFT, "BRACKETRIGHT": KEY_BRACKETRIGHT,
		"SEMICOLON": KEY_SEMICOLON, "APOSTROPHE": KEY_APOSTROPHE,
		"COMMA": KEY_COMMA, "PERIOD": KEY_PERIOD, "SLASH": KEY_SLASH,
		"BACKSLASH": KEY_BACKSLASH, "QUOTELEFT": KEY_QUOTELEFT,
	}
	
	if key_map.has(main_key):
		event.keycode = key_map[main_key]
		return event
	else:
		ctx.log_error("Unknown key: " + main_key)
		return null


## List all input actions defined in the project
static func list_input_actions_op(ctx: SceneTree, params: Dictionary) -> void:
	print("Listing input actions from project settings")
	
	var actions: Array = []
	
	# Get all project settings that start with "input/"
	var property_list: Array = ProjectSettings.get_property_list()
	
	for property in property_list:
		var name: String = property["name"]
		if name.begins_with("input/"):
			var action_name: String = name.substr(6)  # Remove "input/" prefix
			var action_data: Variant = ProjectSettings.get_setting(name)
			
			if ctx.debug_mode:
				print("Found action: " + action_name)
			
			var action_info: Dictionary = {
				"name": action_name,
				"deadzone": action_data.get("deadzone", 0.5) if action_data is Dictionary else 0.5,
				"events": []
			}
			
			# Parse events
			if action_data is Dictionary and action_data.has("events"):
				for event in action_data["events"]:
					var event_info: Dictionary = _parse_input_event(event)
					if event_info:
						action_info["events"].append(event_info)
			
			actions.append(action_info)
	
	# Output as JSON
	var result: Dictionary = {
		"actions": actions,
		"count": actions.size()
	}
	print(JSON.stringify(result))


## Helper function to parse an InputEvent into a readable format
static func _parse_input_event(event: Variant) -> Dictionary:
	var info: Dictionary = {}
	
	if event is InputEventKey:
		info["type"] = "key"
		info["keycode"] = event.keycode
		info["key_name"] = OS.get_keycode_string(event.keycode)
		info["physical_keycode"] = event.physical_keycode
		info["ctrl"] = event.ctrl_pressed
		info["alt"] = event.alt_pressed
		info["shift"] = event.shift_pressed
		info["meta"] = event.meta_pressed
		
		# Build human-readable key string
		var key_parts: Array = []
		if event.ctrl_pressed:
			key_parts.append("Ctrl")
		if event.alt_pressed:
			key_parts.append("Alt")
		if event.shift_pressed:
			key_parts.append("Shift")
		if event.meta_pressed:
			key_parts.append("Meta")
		key_parts.append(OS.get_keycode_string(event.keycode))
		info["display"] = "+".join(key_parts)
		
	elif event is InputEventMouseButton:
		info["type"] = "mouse_button"
		info["button_index"] = event.button_index
		var button_names: Dictionary = {
			MOUSE_BUTTON_LEFT: "Left Click",
			MOUSE_BUTTON_RIGHT: "Right Click",
			MOUSE_BUTTON_MIDDLE: "Middle Click",
			MOUSE_BUTTON_WHEEL_UP: "Wheel Up",
			MOUSE_BUTTON_WHEEL_DOWN: "Wheel Down",
		}
		info["display"] = button_names.get(event.button_index, "Mouse Button " + str(event.button_index))
		
	elif event is InputEventJoypadButton:
		info["type"] = "joypad_button"
		info["button_index"] = event.button_index
		info["display"] = "Joypad Button " + str(event.button_index)
		
	elif event is InputEventJoypadMotion:
		info["type"] = "joypad_motion"
		info["axis"] = event.axis
		info["axis_value"] = event.axis_value
		info["display"] = "Joypad Axis " + str(event.axis) + " (" + ("+" if event.axis_value > 0 else "-") + ")"
	
	else:
		info["type"] = "unknown"
		info["display"] = str(event)
	
	return info
