extends SceneTree

const BattleStateScript := preload("res://scripts/core/battle_state.gd")
const CampaignStateScript := preload("res://scripts/core/campaign_state.gd")

const CAMPAIGN_PATH := "res://data/campaign/campaign.json"
const SAVE_PATH := "user://campaign_save.json"


func _init() -> void:
	var failures: Array[String] = []
	var save_existed := FileAccess.file_exists(SAVE_PATH)
	var save_text := FileAccess.get_file_as_string(SAVE_PATH) if save_existed else ""

	_check_wuchao_gold_pickup_persists_on_victory(failures)
	_restore_save(save_existed, save_text, failures)

	if failures.is_empty():
		print("event gold pickups smoke ok")
		quit(0)
		return

	for failure in failures:
		push_error(failure)
	quit(1)


func _check_wuchao_gold_pickup_persists_on_victory(failures: Array[String]) -> void:
	var campaign_state = CampaignStateScript.new()
	if not campaign_state.load_campaign(CAMPAIGN_PATH):
		failures.append("could not load campaign data")
		return
	campaign_state.start_new(campaign_state.get_start_scenario_id())

	var state = BattleStateScript.new()
	if not state.load_battle(
		campaign_state.get_scenario_path("013_wuchao_raid"),
		campaign_state.get_roster_overrides(),
		campaign_state.get_inventory_snapshot(),
		campaign_state.get_flags_snapshot(),
		campaign_state.get_joined_officers_snapshot()
	):
		failures.append("could not load Wuchao raid")
		return

	var logs: Array[String] = []
	var feedback: Array[String] = []
	state.log_added.connect(func(message: String) -> void:
		logs.append(message)
	)
	state.combat_feedback_requested.connect(func(unit_id: String, text: String, kind: String) -> void:
		feedback.append("%s|%s|%s" % [unit_id, text, kind])
	)

	var cao_cao: Dictionary = state.get_unit("cao_cao_ch13")
	if cao_cao.is_empty():
		failures.append("missing Cao Cao deployment in Wuchao raid")
		return

	cao_cao["pos"] = Vector2i(14, 4)
	state._run_events("unit_reaches_tile", "player", 1, cao_cao)

	if state.get_battle_gold_reward() != 200:
		failures.append("Wuchao depot should add 200 battle gold, got %d" % state.get_battle_gold_reward())
	if not logs.has("Wuchao's captured pay chest yields 200 gold."):
		failures.append("Wuchao gold pickup log missing")
	if not feedback.has("cao_cao_ch13|+200G|gold"):
		failures.append("Wuchao gold pickup feedback missing")

	var active_result: Dictionary = campaign_state.apply_battle_result(state)
	if bool(active_result.get("saved", false)):
		failures.append("active battle should not save event gold before victory")
	if campaign_state.gold != 0:
		failures.append("campaign gold should stay unchanged before victory, got %d" % campaign_state.gold)

	state.battle_status = "victory"
	var result: Dictionary = campaign_state.apply_battle_result(state)
	if not bool(result.get("saved", false)):
		failures.append("campaign save should succeed after Wuchao victory")
	if int(result.get("gold", 0)) != 2300:
		failures.append("Wuchao result should combine base and event gold, got %d" % int(result.get("gold", 0)))
	if campaign_state.gold != 2300:
		failures.append("campaign gold should include event gold after victory, got %d" % campaign_state.gold)

	var before_replay_gold := int(campaign_state.gold)
	var replay_result: Dictionary = campaign_state.apply_battle_result(state)
	if not bool(replay_result.get("already_completed", false)):
		failures.append("second Wuchao apply should be treated as completed replay")
	if campaign_state.gold != before_replay_gold:
		failures.append("completed replay should not duplicate event gold")


func _restore_save(save_existed: bool, save_text: String, failures: Array[String]) -> void:
	if save_existed:
		var file := FileAccess.open(SAVE_PATH, FileAccess.WRITE)
		if file == null:
			failures.append("could not restore previous campaign save")
			return
		file.store_string(save_text)
		return

	if FileAccess.file_exists(SAVE_PATH):
		var error := DirAccess.remove_absolute(ProjectSettings.globalize_path(SAVE_PATH))
		if error != OK:
			failures.append("could not remove temporary campaign save")
