extends Node

## State Manager
## Manages global game state variables - some reset each loop, others persist

signal state_changed(key: String, value: Variant)
signal flag_set(flag: String)
signal flag_cleared(flag: String)

# Variables that reset every loop
var loop_state: Dictionary = {
	# NPCs met this loop
	"npcs_talked_to": [],
	# Items collected this loop
	"items_collected": [],
	# Doors unlocked this loop
	"doors_unlocked": [],
	# Quests completed this loop
	"quests_completed": [],
	# Custom flags (e.g., "beach_door_opened", "found_key")
	"flags": {},
}

# Variables that persist across loops
var persistent_state: Dictionary = {
	# Total loops completed
	"total_loops": 0,
	# Knowledge gained (persists across loops)
	"knowledge": [],
	# Permanent unlocks (abilities, shortcuts)
	"unlocks": [],
	# Story progression flags
	"story_flags": {},
	# Achievements
	"achievements": [],
}

func _ready() -> void:
	print("StateManager initialized")
	TimeManager.loop_completed.connect(_on_loop_completed)

## Loop State (resets each loop)

func set_flag(flag: String, value: bool = true) -> void:
	loop_state.flags[flag] = value
	if value:
		flag_set.emit(flag)
	else:
		flag_cleared.emit(flag)
	state_changed.emit("flag:" + flag, value)

func has_flag(flag: String) -> bool:
	return loop_state.flags.get(flag, false)

func clear_flag(flag: String) -> void:
	set_flag(flag, false)

func add_npc_talked(npc_id: String) -> void:
	if npc_id not in loop_state.npcs_talked_to:
		loop_state.npcs_talked_to.append(npc_id)
		state_changed.emit("npc_talked", npc_id)

func has_talked_to_npc(npc_id: String) -> bool:
	return npc_id in loop_state.npcs_talked_to

func add_item_collected(item_id: String) -> void:
	if item_id not in loop_state.items_collected:
		loop_state.items_collected.append(item_id)
		state_changed.emit("item_collected", item_id)

func has_collected_item(item_id: String) -> bool:
	return item_id in loop_state.items_collected

func unlock_door(door_id: String) -> void:
	if door_id not in loop_state.doors_unlocked:
		loop_state.doors_unlocked.append(door_id)
		state_changed.emit("door_unlocked", door_id)

func is_door_unlocked(door_id: String) -> bool:
	return door_id in loop_state.doors_unlocked

func complete_quest(quest_id: String) -> void:
	if quest_id not in loop_state.quests_completed:
		loop_state.quests_completed.append(quest_id)
		state_changed.emit("quest_completed", quest_id)

func is_quest_completed(quest_id: String) -> bool:
	return quest_id in loop_state.quests_completed

## Persistent State (survives loops)

func add_knowledge(knowledge_id: String) -> void:
	if knowledge_id not in persistent_state.knowledge:
		persistent_state.knowledge.append(knowledge_id)
		state_changed.emit("knowledge_gained", knowledge_id)
		print("Knowledge gained: ", knowledge_id)

func has_knowledge(knowledge_id: String) -> bool:
	return knowledge_id in persistent_state.knowledge

func add_unlock(unlock_id: String) -> void:
	if unlock_id not in persistent_state.unlocks:
		persistent_state.unlocks.append(unlock_id)
		state_changed.emit("unlock_gained", unlock_id)
		print("Unlock gained: ", unlock_id)

func has_unlock(unlock_id: String) -> bool:
	return unlock_id in persistent_state.unlocks

func set_story_flag(flag: String, value: bool = true) -> void:
	persistent_state.story_flags[flag] = value
	state_changed.emit("story_flag:" + flag, value)

func has_story_flag(flag: String) -> bool:
	return persistent_state.story_flags.get(flag, false)

func add_achievement(achievement_id: String) -> void:
	if achievement_id not in persistent_state.achievements:
		persistent_state.achievements.append(achievement_id)
		state_changed.emit("achievement_unlocked", achievement_id)
		print("Achievement unlocked: ", achievement_id)

func has_achievement(achievement_id: String) -> bool:
	return achievement_id in persistent_state.achievements

## Loop Management

func _on_loop_completed() -> void:
	print("Loop completed - resetting loop state")
	persistent_state.total_loops += 1
	_reset_loop_state()

func _reset_loop_state() -> void:
	loop_state = {
		"npcs_talked_to": [],
		"items_collected": [],
		"doors_unlocked": [],
		"quests_completed": [],
		"flags": {},
	}
	state_changed.emit("loop_reset", persistent_state.total_loops)

func reset_all() -> void:
	"""Called when starting a new game"""
	_reset_loop_state()
	persistent_state = {
		"total_loops": 0,
		"knowledge": [],
		"unlocks": [],
		"story_flags": {},
		"achievements": [],
	}

## Save/Load Support

func get_save_data() -> Dictionary:
	return {
		"loop_state": loop_state.duplicate(true),
		"persistent_state": persistent_state.duplicate(true),
	}

func load_save_data(data: Dictionary) -> void:
	if data.has("loop_state"):
		loop_state = data.loop_state.duplicate(true)
	if data.has("persistent_state"):
		persistent_state = data.persistent_state.duplicate(true)
