extends SceneTree

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


func _init() -> void:
	var failures: Array[String] = []
	_check_defeat_event_log(failures)
	_check_defeat_event_can_delay_victory(failures)

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

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


func _check_defeat_event_log(failures: Array[String]) -> void:
	var state = _loaded_state(failures, "defeat event log")
	if state == null:
		return
	var logs := []
	state.log_added.connect(func(message: String) -> void:
		logs.append(message)
	)
	state.fired_event_ids.clear()
	state.battle_events.clear()
	state.battle_events.append({
		"id": "zhang_mancheng_falls",
		"once": true,
		"when": {"type": "unit_defeated", "unit_ids": ["yellow_turban_1"]},
		"actions": [
			{"type": "log", "text": "Zhang Mancheng's banner falls."}
		]
	})

	_defeat_unit_with_skill(state, "yellow_turban_1")
	if not logs.has("Zhang Mancheng's banner falls."):
		failures.append("unit_defeated event log did not fire")
	if not state.fired_event_ids.has("zhang_mancheng_falls"):
		failures.append("unit_defeated event id was not recorded")


func _check_defeat_event_can_delay_victory(failures: Array[String]) -> void:
	var state = _loaded_state(failures, "defeat event victory delay")
	if state == null:
		return
	for enemy in state.get_living_units("enemy"):
		if str(enemy.get("id", "")) != "yellow_turban_1":
			enemy["alive"] = false
	state.fired_event_ids.clear()
	state.battle_events.clear()
	state.battle_events.append({
		"id": "last_rebel_reserve_arrives",
		"once": true,
		"when": {"type": "unit_defeated", "unit_ids": ["yellow_turban_1"]},
		"actions": [
			{
				"type": "spawn_deployment",
				"deployment": {
					"unit_id": "last_rebel_reserve",
					"name": "Last Rebel Reserve",
					"class_id": "bandit",
					"team": "enemy",
					"level": 1,
					"pos": [5, 5],
					"base": {"hp": 24, "atk": 9, "def": 4}
				}
			}
		]
	})

	_defeat_unit_with_skill(state, "yellow_turban_1")
	var reserve: Dictionary = state.get_unit("last_rebel_reserve")
	if reserve.is_empty() or not bool(reserve.get("alive", false)) or not bool(reserve.get("deployed", true)):
		failures.append("unit_defeated reinforcement did not arrive alive and deployed")
	if str(state.battle_status) != "active":
		failures.append("unit_defeated reinforcement should keep battle active, got %s" % str(state.battle_status))


func _loaded_state(failures: Array[String], label: String):
	var state = BattleStateScript.new()
	if not state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
		failures.append("%s could not load smoke scenario" % label)
		return null
	return state


func _defeat_unit_with_skill(state, unit_id: String) -> void:
	var caster: Dictionary = state.get_unit("cao_cao")
	var target: Dictionary = state.get_unit(unit_id)
	target["hp"] = 1
	state._resolve_skill_damage(caster, target, {
		"name": "Smoke Bolt",
		"power": 99,
		"stat": "int"
	})
