extends Node
## StateManager Service
##
## Singleton service for managing global application state.
## Handles user session, character data, wizard state, navigation, and persistence.
##
## Usage:
##   StateManager.set_user_session(user_data)
##   var user = StateManager.get_current_user()
##   StateManager.save_state()  # Persist to local storage

# Signals for state changes
signal user_logged_in(user_data: Dictionary)
signal user_logged_out()
signal character_selected(character_id: String)
signal character_created(character_data: Dictionary)
signal character_deleted(character_id: String)
signal characters_updated(characters: Array)

# Save file configuration
const SAVE_FILE_PATH := "user://coc_state.save"
const SAVE_VERSION := 1

# User session state
var _current_user: Dictionary = {}
var _auth_token: String = ""
var _is_authenticated: bool = false

# Character state
var _characters: Array[Dictionary] = []
var _selected_character_id: String = ""
var _character_limits: Dictionary = {}

# Character creation wizard state
var _wizard_state: Dictionary = {
	"step": 0,  # Current step (0-3)
	"selected_origin": null,  # Selected origin data
	"selected_class": null,  # Selected class data
	"character_name": "",
	"character_customization": {}
}

# Navigation state
var _current_scene: String = ""
var _scene_history: Array[String] = []

# Settings (deprecated - use Settings service for preferences)
# Kept for backward compatibility with save files
var _settings: Dictionary = {
	"remember_login": true,
	"auto_save": true
}

# Reference to HTTPClient singleton (available after _ready)
@onready var http_client: Node = get_node("/root/HTTPClient")


func _ready() -> void:
	print("[StateManager] Service initialized")
	_load_state()


## Set user session data (after login/registration)
func set_user_session(user_data: Dictionary, token: String = "") -> void:
	_current_user = user_data
	_auth_token = token
	_is_authenticated = true

	# Update HTTPClient with token (if using JWT auth)
	if not token.is_empty():
		http_client.set_auth_token(token)

	print("[StateManager] User session set: %s" % user_data.get("email", "unknown"))

	# Emit signal
	user_logged_in.emit(user_data)

	# Auto-save if enabled
	if _settings.get("auto_save", true):
		save_state()


## Clear user session (logout)
func clear_user_session() -> void:
	_current_user = {}
	_auth_token = ""
	_is_authenticated = false
	_characters = []
	_selected_character_id = ""

	# Clear HTTPClient token and cookie
	http_client.clear_auth_token()
	http_client.clear_session_cookie()

	print("[StateManager] User session cleared")

	# Emit signal
	user_logged_out.emit()

	# Clear saved state
	_clear_save_file()


## Get current user data
func get_current_user() -> Dictionary:
	return _current_user


## Get current auth token
func get_auth_token() -> String:
	return _auth_token


## Check if user is authenticated
func is_authenticated() -> bool:
	# Check both token and cookie-based auth
	return _is_authenticated and (not _auth_token.is_empty() or http_client.is_authenticated())


## Set characters list
func set_characters(characters: Array) -> void:
	_characters.clear()
	for character in characters:
		_characters.append(character)

	print("[StateManager] Characters updated: %d total" % _characters.size())

	# Emit signal
	characters_updated.emit(_characters)

	# Auto-save if enabled
	if _settings.get("auto_save", true):
		save_state()


## Get all characters
func get_characters() -> Array[Dictionary]:
	return _characters


## Add character to list
func add_character(character_data: Dictionary) -> void:
	_characters.append(character_data)

	print("[StateManager] Character added: %s" % character_data.get("name", "unknown"))

	# Emit signal
	character_created.emit(character_data)

	# Auto-save if enabled
	if _settings.get("auto_save", true):
		save_state()


## Remove character from list
func remove_character(character_id: String) -> void:
	for i in range(_characters.size()):
		if _characters[i].get("id") == character_id:
			_characters.remove_at(i)
			print("[StateManager] Character removed: %s" % character_id)

			# Clear selection if this was selected
			if _selected_character_id == character_id:
				_selected_character_id = ""

			# Emit signal
			character_deleted.emit(character_id)

			# Auto-save if enabled
			if _settings.get("auto_save", true):
				save_state()
			return


## Get character by ID
func get_character(character_id: String) -> Dictionary:
	for character in _characters:
		if character.get("id") == character_id:
			return character
	return {}


## Set selected character
func select_character(character_id: String) -> void:
	_selected_character_id = character_id
	print("[StateManager] Character selected: %s" % character_id)

	# Emit signal
	character_selected.emit(character_id)


## Get selected character
func get_selected_character() -> Dictionary:
	return get_character(_selected_character_id)


## Get selected character ID
func get_selected_character_id() -> String:
	return _selected_character_id


## Set character limits
func set_character_limits(limits: Dictionary) -> void:
	_character_limits = limits


## Get character limits
func get_character_limits() -> Dictionary:
	return _character_limits


## Character Creation Wizard State Management

## Reset wizard state
func reset_wizard() -> void:
	_wizard_state = {
		"step": 0,
		"selected_origin": null,
		"selected_class": null,
		"character_name": "",
		"character_customization": {}
	}
	print("[StateManager] Wizard state reset")


## Set wizard step
func set_wizard_step(step: int) -> void:
	_wizard_state["step"] = step


## Get current wizard step
func get_wizard_step() -> int:
	return _wizard_state.get("step", 0)


## Set selected origin
func set_wizard_origin(origin_data: Dictionary) -> void:
	_wizard_state["selected_origin"] = origin_data


## Get selected origin
func get_wizard_origin() -> Dictionary:
	return _wizard_state.get("selected_origin", {})


## Set selected class
func set_wizard_class(class_data: Dictionary) -> void:
	_wizard_state["selected_class"] = class_data


## Get selected class
func get_wizard_class() -> Dictionary:
	return _wizard_state.get("selected_class", {})


## Set character name
func set_wizard_name(char_name: String) -> void:
	_wizard_state["character_name"] = char_name


## Get character name
func get_wizard_name() -> String:
	return _wizard_state.get("character_name", "")


## Set character customization
func set_wizard_customization(customization: Dictionary) -> void:
	_wizard_state["character_customization"] = customization


## Get character customization
func get_wizard_customization() -> Dictionary:
	return _wizard_state.get("character_customization", {})


## Get complete wizard state
func get_wizard_state() -> Dictionary:
	return _wizard_state


## Navigation State Management

## Set current scene
func set_current_scene(scene_path: String) -> void:
	if not _current_scene.is_empty():
		_scene_history.append(_current_scene)

	_current_scene = scene_path
	print("[StateManager] Scene changed: %s" % scene_path)


## Get current scene
func get_current_scene() -> String:
	return _current_scene


## Navigate back
func navigate_back() -> String:
	if _scene_history.is_empty():
		return ""

	var previous_scene: String = _scene_history.pop_back()
	_current_scene = previous_scene
	return previous_scene


## Can navigate back
func can_navigate_back() -> bool:
	return not _scene_history.is_empty()


## Settings Management

## Get setting value
func get_setting(key: String, default: Variant = null) -> Variant:
	return _settings.get(key, default)


## Set setting value
func set_setting(key: String, value: Variant) -> void:
	_settings[key] = value
	print("[StateManager] Setting updated: %s = %s" % [key, value])

	# Auto-save if enabled
	if _settings.get("auto_save", true):
		save_state()


## Get all settings
func get_settings() -> Dictionary:
	return _settings


## Persistence (Save/Load)

## Save state to disk
func save_state() -> void:
	var save_data := {
		"version": SAVE_VERSION,
		"user": _current_user,
		"auth_token": _auth_token if _settings.get("remember_login", true) else "",
		"session_cookie": http_client.get_session_cookie() if _settings.get("remember_login", true) else "",
		"is_authenticated": _is_authenticated if _settings.get("remember_login", true) else false,
		"characters": _characters,
		"selected_character_id": _selected_character_id,
		"character_limits": _character_limits,
		"settings": _settings,
		"timestamp": Time.get_unix_time_from_system()
	}

	var file := FileAccess.open(SAVE_FILE_PATH, FileAccess.WRITE)
	if file == null:
		push_error("[StateManager] Failed to open save file for writing: %s" % FileAccess.get_open_error())
		return

	file.store_string(JSON.stringify(save_data))
	file.close()

	print("[StateManager] State saved to %s" % SAVE_FILE_PATH)


## Load state from disk
func _load_state() -> void:
	if not FileAccess.file_exists(SAVE_FILE_PATH):
		print("[StateManager] No save file found, starting fresh")
		return

	var file := FileAccess.open(SAVE_FILE_PATH, FileAccess.READ)
	if file == null:
		push_error("[StateManager] Failed to open save file for reading: %s" % FileAccess.get_open_error())
		return

	var json_string := file.get_as_text()
	file.close()

	var json := JSON.new()
	var parse_error := json.parse(json_string)

	if parse_error != OK:
		push_error("[StateManager] Failed to parse save file")
		return

	var save_data: Dictionary = json.data

	# Check version
	if save_data.get("version", 0) != SAVE_VERSION:
		print("[StateManager] Save file version mismatch, ignoring")
		return

	# Restore state
	_current_user = save_data.get("user", {})
	_auth_token = save_data.get("auth_token", "")
	_is_authenticated = save_data.get("is_authenticated", false)
	_characters = []

	# Convert characters array
	var chars_data = save_data.get("characters", [])
	for character in chars_data:
		_characters.append(character)

	_selected_character_id = save_data.get("selected_character_id", "")
	_character_limits = save_data.get("character_limits", {})
	_settings = save_data.get("settings", _settings)

	# Update HTTPClient with token if authenticated
	if _is_authenticated and not _auth_token.is_empty():
		http_client.set_auth_token(_auth_token)

	# Restore session cookie if present
	var session_cookie = save_data.get("session_cookie", "")
	if _is_authenticated and not session_cookie.is_empty():
		http_client.set_session_cookie(session_cookie)

	print("[StateManager] State loaded from %s" % SAVE_FILE_PATH)
	print("[StateManager] Authenticated: %s, Characters: %d" % [_is_authenticated, _characters.size()])


## Clear save file
func _clear_save_file() -> void:
	if FileAccess.file_exists(SAVE_FILE_PATH):
		DirAccess.remove_absolute(SAVE_FILE_PATH)
		print("[StateManager] Save file cleared")
