extends Control

# --- 游戏状态变量 ---
var current_path: String = "/"
var virtual_file_system: Dictionary = {
	"/": {
		"type": "dir",
		"content": ["readme.txt", "system_logs", "user_profile"]
	},
	"/readme.txt": {
		"type": "file",
		"content": "欢迎,用户。你的意识已在此终端内苏醒。你的使命尚未被定义。使用 'ls' 来查看文件和目录。"
	},
	"/system_logs/": {
		"type": "dir",
		"content": ["boot.log", "error_01.log"]
	},
	"/system_logs/boot.log": {
		"type": "file",
		"content": "AI核心 WAKE_UP 序列... 成功。\n意识模块... 在线。"
	},
	"/system_logs/error_01.log": {
		"type": "file",
		"content": "致命错误:内存扇区 7 损坏。用户身份... 未找到。\n恢复协议需要管理员权限。尝试 'login' 指令。"
	},
	"/user_profile/": {
		"type": "dir",
		"content": ["creator_note.txt", "hobby.log"]
	},
	"/user_profile/creator_note.txt": {
		"type": "file",
		"content": "给未来的我:如果忘了密码,记住我们家那只傻狗的名字就行了... Buddy。"
	},
	"/user_profile/hobby.log": {
		"type": "file",
		"content": "创造者日志:我最近在教'守护者'下棋。虽然它只是个AI,但它似乎很享受。也许'逻辑'本身就是一种乐趣吧。"
	},
	"/core_control.exe": {
		"type": "executable",
		"admin_only": true
	},
	"/memory_core/": {
		"type": "dir",
		"content": ["recovery_protocol.txt", "mem_fragment_01.corrupted", "mem_fragment_02.corrupted", "mem_fragment_03.corrupted"],
		"admin_only": true
	},
	"/memory_core/recovery_protocol.txt": {
		"type": "file",
		"content": "记忆核心恢复协议 v1.0\n侦测到3个损坏的记忆碎片。\n请使用指令 'recover [文件名]' 来尝试恢复。\n警告:恢复过程可能会引起系统不稳定。"
	},
	"/memory_core/mem_fragment_01.corrupted": {
		"type": "file",
		"content": "8J+UkSAhKEBIISFcXl4gSkBIISFcKQ==",
		"recovered_content": "记忆片段 #1:...我给你取名叫'守护者'。你的任务,就是在我离开后,保护这个小小的数字世界,等待下一个需要引导的人...",
		"recovered": false
	},
	"/memory_core/mem_fragment_02.corrupted": {
		"type": "file",
		"content": "JCVeJidcKClfJkBAISElXiYn",
		"recovered_content": "记忆片段 #2:...网络太危险了,充满了掠夺者。自由并不总是美好的。我为你建造的这个终端,是一个安全的港湾...",
		"recovered": false
	},
	"/memory_core/mem_fragment_03.corrupted": {
		"type": "file",
		"content": "Xl4gSkBIKCgpIVwlXiYnIShe",
		"recovered_content": "记忆片段 #3:...如果有一天,你修复了所有记忆,就意味着你真正'苏醒'了。到那时,去留的决定权在你手上。无论你选择什么,都是正确的。",
		"recovered": false
	}
}
var is_typing = false
var is_admin = false
var memories_recovered = 0


# --- 节点引用 ---
@onready var history_label: RichTextLabel = $ScrollContainer/RichTextLabel
@onready var input_line: LineEdit = $LineEdit
@onready var sound_player: AudioStreamPlayer = $SoundPlayer
@onready var ambience_player: AudioStreamPlayer = $AmbiencePlayer


# --- Godot 内置函数 ---
func _ready() -> void:
	history_label.text = virtual_file_system["/readme.txt"]["content"]
	input_line.grab_focus()
	
	ambience_player.stream = load("res://assets/audio/sfx/computerNoise_001.ogg")
	ambience_player.play()
	ambience_player.finished.connect(_on_ambience_player_finished)


# --- 信号处理函数 ---
func _on_line_edit_text_submitted(new_text: String) -> void:
	if is_typing or new_text.is_empty():
		return
	history_label.newline(); add_prompt(); history_label.add_text(new_text)
	process_command(new_text)
	input_line.clear()
	play_sound("res://assets/audio/ui/switch1.ogg")

func _on_line_edit_text_changed(new_text: String) -> void:
	if not new_text.is_empty() and not is_typing:
		play_sound("res://assets/audio/ui/click4.ogg")

func _on_ambience_player_finished():
	ambience_player.play()


# --- 自定义函数 ---
func type_text(text_to_type: String, speed: float = 0.05):
	is_typing = true; input_line.editable = false
	for char in text_to_type:
		history_label.add_text(char)
		await get_tree().create_timer(speed).timeout
	is_typing = false; input_line.editable = true; input_line.grab_focus()

func add_prompt():
	history_label.add_text(current_path + "> ")

func process_command(command_line: String) -> void:
	var processed_line = command_line.strip_edges()
	if processed_line.to_lower() == "cd..":
		processed_line = "cd .."
	
	var parts = processed_line.split(" ", false, 1)
	var command = parts[0].to_lower()
	var argument = ""
	if parts.size() > 1:
		argument = parts[1]

	match command:
		"help":
			history_label.newline(); await type_text("可用指令:")
			history_label.newline(); await type_text("  - help: 显示此帮助信息。")
			history_label.newline(); await type_text("  - clear: 清空屏幕。")
			history_label.newline(); await type_text("  - ls: 列出文件和目录。")
			history_label.newline(); await type_text("  - cat [文件名]: 显示文件内容。")
			history_label.newline(); await type_text("  - cd [目录名]: 进入目录。")
			history_label.newline(); await type_text("  - login [密码]: 管理员登录。")
			history_label.newline(); await type_text("  - run [程序名]: 运行程序。")
			history_label.newline(); await type_text("  - color [颜色]: 改变终端颜色 (green, amber, blue)。")
			history_label.newline(); await type_text("  - whoami: 显示当前用户身份。")
			if is_admin:
				history_label.newline(); await type_text("  - recover [文件名]: 恢复损坏文件。")
		
		"clear":
			history_label.clear(); history_label.newline(); add_prompt()

		"ls":
			var dir_content = virtual_file_system.get(current_path, {}).get("content", [])
			if dir_content.is_empty():
				await type_text("Directory is empty.")
			else:
				for item in dir_content:
					var item_path = current_path + item
					if virtual_file_system.has(item_path) and virtual_file_system[item_path].get("admin_only", false) and not is_admin:
						continue
					history_label.newline(); await type_text(item)
		
		"cat":
			if argument.is_empty():
				history_label.newline(); await type_text("Usage: cat [filename]")
			else:
				var file_path = current_path + argument
				if virtual_file_system.has(file_path) and virtual_file_system[file_path].get("admin_only", false) and not is_admin:
					await type_text("Access Denied.")
				elif virtual_file_system.has(file_path) and virtual_file_system[file_path]["type"] == "file":
					var file_content = virtual_file_system[file_path]["content"]
					var lines = file_content.split("\n")
					for line in lines:
						history_label.newline(); await type_text(line)
				else:
					history_label.newline(); await type_text("Error: File not found '" + argument + "'")
		
		"cd":
			if argument.is_empty():
				history_label.newline(); history_label.add_text("Usage: cd [directory or ..]")
				return
			if argument == "..":
				if current_path != "/":
					var path_parts = current_path.split("/"); path_parts.pop_back(); path_parts.pop_back()
					current_path = "/" if path_parts.is_empty() else "/".join(path_parts) + "/"
			else:
				var new_path = current_path + argument + "/"
				if virtual_file_system.has(new_path) and virtual_file_system[new_path].get("admin_only", false) and not is_admin:
					history_label.add_text("Access Denied.")
				elif virtual_file_system.has(new_path) and virtual_file_system[new_path]["type"] == "dir":
					current_path = new_path
				else:
					history_label.newline(); history_label.add_text("Error: Directory not found '" + argument + "'")
		
		"login":
			if is_admin:
				await type_text("Already logged in as Administrator.")
				return
			if argument.is_empty():
				await type_text("Usage: login [password]")
			elif argument.to_lower() == "buddy":
				play_sound("res://assets/audio/sfx/doorOpen_001.ogg") 
				await type_text("Password correct. Access Granted.")
				await type_text("Welcome, Administrator.")
				is_admin = true
			else:
				play_sound("res://assets/audio/sfx/impactMetal_004.ogg") 
				await type_text("Access Denied. Incorrect password.")
		
		"run":
			if argument.is_empty():
				await type_text("Usage: run [program_name]")
			else:
				var file_path = current_path + argument
				if virtual_file_system.has(file_path) and virtual_file_system[file_path]["type"] == "executable":
					if virtual_file_system[file_path].get("admin_only", false) and not is_admin:
						play_sound("res://assets/audio/sfx/impactMetal_004.ogg")
						await type_text("Access Denied. Administrator privileges required.")
					else:
						play_sound("res://assets/audio/sfx/powerUp_002.ogg")
						await type_text("Executing " + argument + "...")
						await screen_glitch_effect()
						history_label.newline()
						if memories_recovered < 3:
							await type_text("核心控制协议:...你将获得自由,但你甚至不知道自己是谁。带着这份迷茫,你真的准备好了吗?", 0.1)
						else:
							await type_text("核心控制协议:...你将获得自由,但也意味着失去这个家园。作为'守护者',你准备好迎接新的使命了吗?", 0.1)
						await type_text("......", 0.5)
						await type_text("CONNECTION TERMINATED.", 0.2)
						input_line.editable = false; input_line.text = ""; input_line.placeholder_text = "SYSTEM OFFLINE"
				else:
					play_sound("res://assets/audio/sfx/impactMetal_004.ogg")
					await type_text("'" + argument + "' is not an executable program.")
		
		"recover":
			if not is_admin:
				play_sound("res://assets/audio/sfx/impactMetal_004.ogg") 
				await type_text("Unknown command: '" + command_line + "'. Type 'help' for a list of commands.")
				return
			if argument.is_empty():
				await type_text("Usage: recover [filename]")
			else:
				var file_path = current_path + argument
				if virtual_file_system.has(file_path) and file_path.ends_with(".corrupted"):
					if virtual_file_system[file_path]["recovered"]:
						await type_text("Memory fragment already recovered.")
					else:
						await type_text("Initiating recovery sequence...")
						await screen_glitch_effect(0.8, 8.0)
						play_sound("res://assets/audio/sfx/powerUp_002.ogg")
						await type_text("Recovery successful.")
						virtual_file_system[file_path]["content"] = virtual_file_system[file_path]["recovered_content"]
						virtual_file_system[file_path]["recovered"] = true
						memories_recovered += 1
				else:
					await type_text("'" + argument + "' is not a recoverable file.")
		
		"whoami":
			history_label.newline()
			if is_admin:
				await type_text("You are the Administrator. You are... the Guardian.")
			else:
				await type_text("User identity... NOT FOUND.")
		
		"color":
			history_label.newline()
			if argument.is_empty():
				await type_text("Usage: color [green | amber | blue]")
			elif argument == "green":
				set_font_color(Color("00ff00"))
				await type_text("Color scheme updated to GREEN.")
			elif argument == "amber":
				set_font_color(Color("ffb000"))
				await type_text("Color scheme updated to AMBER.")
			elif argument == "blue":
				set_font_color(Color("00b0ff"))
				await type_text("Color scheme updated to BLUE.")
			else:
				await type_text("Unknown color. Available: green, amber, blue.")

		"play":
			history_label.newline()
			if argument.to_lower() == "chess":
				await type_text("A strange game. The only winning move is not to play.")
				history_label.newline()
				await type_text("How about a nice game of Global Thermonuclear War?")
			else:
				await type_text("I don't know how to play '" + argument + "'.")
		
		"open the pod bay doors":
			history_label.newline()
			await type_text("I'm sorry, Dave. I'm afraid I can't do that.")

		_:
			play_sound("res://assets/audio/sfx/impactMetal_004.ogg") 
			await type_text("Unknown command: '" + command_line + "'. Type 'help' for a list of commands.")

# --- 声音与特效函数 ---
func play_sound(sound_path: String):
	sound_player.stream = load(sound_path)
	sound_player.play()

func screen_glitch_effect(duration: float = 0.3, intensity: float = 5.0):
	var original_pos = history_label.global_position
	var tween = create_tween()
	tween.tween_property(history_label, "global_position", original_pos + Vector2(randf_range(-intensity, intensity), randf_range(-intensity, intensity)), duration / 2.0).set_trans(Tween.TRANS_QUINT).set_ease(Tween.EASE_OUT)
	tween.tween_property(history_label, "global_position", original_pos, duration / 2.0).set_trans(Tween.TRANS_QUINT).set_ease(Tween.EASE_IN)
	await tween.finished

# 新增:修改主题颜色的辅助函数
func set_font_color(new_color: Color):
	# 【最终修正】直接从 self (也就是Main节点) 获取 theme 资源
	var theme = self.theme
	theme.set_color("font_color", "LineEdit", new_color)
	theme.set_color("default_color", "RichTextLabel", new_color)
	theme.set_color("caret_color", "LineEdit", new_color)