class_name BossRemnantManager
extends Node

var starting_position : Vector2 = Vector2.ZERO
var is_recording : bool = false
var recording_time : float = 0
var stored_recording_time : float = 0
var player_remnant_active : bool = false
var recording : Array[BossRecording]
var temporary_recording : Array[BossRecording]
var attack_recording : PackedInt32Array
var temporary_attack_recording : PackedInt32Array
var direction_recording : PackedVector2Array
var temporary_direction_recording : PackedVector2Array

var boss_remnant_scene = preload("res://scenes/nodes/boss/boss_remnant/boss_remnant.tscn")

func _ready() -> void:
	SignalBus.set_anchor.connect(_player_set_anchored_remnant)
	SignalBus.reload_anchor.connect(_player_reload_anchored_remnant)
	SignalBus.anchor_ran_out.connect(_player_anchored_remnant_ran_out)
	SignalBus.boss_reload_anchor.connect(reload_setup)

func init():
	SignalBus.emit_boss_set_anchor()
	start_recording()

func start_recording():
	is_recording = true

func pause_recording():
	is_recording = false

func reload_setup():
	is_recording = false
	recording.append_array(temporary_recording)
	attack_recording.append_array(temporary_attack_recording)
	
	# instantiate boss remnant
	var boss_remnant = boss_remnant_scene.instantiate() as BossRemnant
	# assign to room scene
	if get_parent().get_parent() is Boss:
		var boss : Boss = get_parent().get_parent()
		boss.get_parent().add_child.call_deferred(boss_remnant)
		boss_remnant.global_position = starting_position
		boss_remnant.init(boss.speed, boss.map_loader, recording, attack_recording, direction_recording)

func _process(delta: float) -> void:
	if Globals.paused:
		return
	if is_recording:
		recording_time += delta

#region Action Recording
## for dying
func nothing():
	_append_action(Utils.BOSS_ACTIONS.NOTHING)

func time_shift(time : Utils.TIME = Globals.current_time):
	match time:
		Utils.TIME.PRESENT:
			_append_action(Utils.BOSS_ACTIONS.TIME_SHIFT_TO_PRESENT)
		Utils.TIME.PAST:
			_append_action(Utils.BOSS_ACTIONS.TIME_SHIFT_TO_PAST)

func stunned_start():
	_append_action(Utils.BOSS_ACTIONS.STUNNED_START)

func stunned_end():
	_append_action(Utils.BOSS_ACTIONS.STUNNED_END)

func attack(attack_id : int):
	_append_attack(attack_id)

func prepare_attack():
	_append_action(Utils.BOSS_ACTIONS.PREPARE_ATTACK)

func perform_attack():
	_append_action(Utils.BOSS_ACTIONS.PERFORM_ATTACK)

func attack_cooldown():
	_append_action(Utils.BOSS_ACTIONS.ATTACK_COOLDOWN)

func _append_action(action : Utils.BOSS_ACTIONS):
	if Globals.paused or not is_recording:
		return
	var recorded_action = BossRecording.new()
	recorded_action.init(recording_time, action)
	if player_remnant_active:
		temporary_recording.append(recorded_action)
	else:
		recording.append(recorded_action)

func _append_attack(attack_id : int):
	if Globals.paused or not is_recording:
		return
	if player_remnant_active:
		temporary_attack_recording.append(attack_id)
	else:
		attack_recording.append(attack_id)

func append_movement(direction : Vector2):
	_append_action(Utils.BOSS_ACTIONS.MOVEMENT)
	if Globals.paused or not is_recording:
		return
	if player_remnant_active:
		temporary_direction_recording.append(direction)
	else:
		direction_recording.append(direction)
#endregion

#region Anchored Remnant
func _player_set_anchored_remnant():
	player_remnant_active = true
	stored_recording_time = recording_time

func _player_reload_anchored_remnant():
	temporary_recording.clear()
	temporary_attack_recording.clear()
	temporary_direction_recording.clear()
	recording_time = stored_recording_time

func _player_anchored_remnant_ran_out():
	player_remnant_active = false
	recording.append_array(temporary_recording)
	attack_recording.append_array(temporary_attack_recording)
	direction_recording.append_array(temporary_direction_recording)
#endregion
