# scripts/settings/SettingsModel.gd
extends Node
class_name SettingsModel

## ===============================
## Dependencies
## ===============================
const SettingsSchema  = preload("res://__settings/SettingSchema.gd")
const SettingsStorage = preload("res://__settings/SettingStorage.gd")

## ===============================
## Signals
## ===============================
signal setting_changed(section: String, key: String, value)
signal settings_applied
signal settings_reverted

## ===============================
## Internal State
## ===============================
var _data_committed : Dictionary = {}   # 已生效 / 已保存
var _data_working   : Dictionary = {}   # UI 正在修改
var _storage := SettingsStorage.new()

## ===============================
## Lifecycle
## ===============================
func _ready() -> void:
	_load()

## ===============================
## Public API (Read)
## ===============================
func get_setting(section: String, key: String) -> Variant:
	return _data_working.get(section, {}).get(key)

func get_section(section: String) -> Dictionary:
	return _data_working.get(section, {}).duplicate(true)

## ===============================
## Public API (Write - Working Only)
## ===============================
func set_setting(section: String, key: String, value: Variant) -> void:
	if not _data_working.has(section):
		_data_working[section] = {}

	_data_working[section][key] = value
	emit_signal("setting_changed", section, key, value)

## ===============================
## Typed Getters
## ===============================
func get_bool(section: String, key: String) -> bool:
	var value = get_setting(section, key)
	return value if typeof(value) == TYPE_BOOL else false

func get_int(section: String, key: String) -> int:
	var value = get_setting(section, key)
	return value if typeof(value) == TYPE_INT else 0

func get_float(section: String, key: String) -> float:
	var value = get_setting(section, key)
	if typeof(value) == TYPE_FLOAT or typeof(value) == TYPE_INT:
		return float(value)
	return 0.0

func get_string(section: String, key: String) -> String:
	var value = get_setting(section, key)
	return value if typeof(value) == TYPE_STRING else ""

## ===============================
## Transaction Control
## ===============================
func apply() -> void:
	_data_committed = _data_working.duplicate(true)

	for section in _data_committed.keys():
		for key in _data_committed[section].keys():
			_storage.set_value(section, key, _data_committed[section][key])

	_storage.save()
	emit_signal("settings_applied")

func revert() -> void:
	_data_working = _data_committed.duplicate(true)
	emit_signal("settings_reverted")

func has_unsaved_changes() -> bool:
	return _data_working != _data_committed

## ===============================
## Internal
## ===============================
func _load() -> void:
	_storage.load()

	# 1. Load defaults
	_data_committed = SettingsSchema.defaults().duplicate(true)

	# 2. Override with saved values
	for section in _data_committed.keys():
		for key in _data_committed[section].keys():
			var default_value = _data_committed[section][key]
			var value = _storage.get_value(section, key, default_value)
			_data_committed[section][key] = value

	# 3. Init working copy
	_data_working = _data_committed.duplicate(true)
