class_name EnergyPillar
extends Interactable

@onready var tmp_sprite: Sprite2D = $TmpSprite
@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
@onready var energy_ball: Node2D = $EnergyBall

@export var is_start: bool
@export var is_end: bool
@export var next_pillar: EnergyPillar
#var is_holding_energy_ball: bool = false  # is "active"
var is_sending_energy_ball: bool = false
var energy_ball_progress = 0.0  # between 0 and 1. 0 is at base, 1 is at next station.
@export var energy_ball_speed = 1.0
@export var die_down_time = 2.0
var timer: float

# save state vars
var saved_state_is_sending_energy_ball = false
var saved_state_energy_ball_progress = false
var saved_state_timer: float

# when hit, 
func _ready() -> void:
	super()  # to connect to save and load state
	if is_start:
		active = true
		_update_sprite()
	timer = die_down_time
	
	if is_end:  # disable sprites and collision
		collision_shape_2d.disabled = true
		#tmp_sprite.visible = false  # better to be visible, so people get to let it move on

func _process(delta: float) -> void:
	if Globals.paused or SceneChanger.mid_change or SceneChanger.mid_animation:
		return
	# send energy ball towards next pillar
	if is_sending_energy_ball:
		energy_ball_progress += delta * energy_ball_speed
		energy_ball.global_position = global_position + (next_pillar.global_position - global_position) * energy_ball_progress
		
	# reached next station
		if energy_ball_progress >= 1:  
			is_sending_energy_ball = false
			_update_sprite()
			if next_pillar:
				next_pillar.reached_by_energy_ball()
				
	# energy ball dies down slowly if it stays on pillar
	elif active and not is_start and not is_end:  
		timer -= delta
		var power_left = timer / die_down_time
		energy_ball.scale = Vector2(power_left, power_left)
		if timer < 0.0:
			active = false
			_update_sprite()
			# save globally
			Globals.interactable_states[get_path()] = active
	
	 # to visually have the respawn of the energy ball
	if is_start and not is_sending_energy_ball: 
		energy_ball.global_position = global_position
	
	
func switch_state():  # when hit
	#super()  # on purpose not calling super for now
	if active and not is_end:
		send_energy_ball()
	
		
		
func _save_state():
	super()
	saved_state_energy_ball_progress = energy_ball_progress
	saved_state_is_sending_energy_ball = is_sending_energy_ball
	saved_state_timer = timer 

func _load_saved_state():
	super()
	energy_ball_progress = saved_state_energy_ball_progress
	is_sending_energy_ball = saved_state_is_sending_energy_ball
	timer = saved_state_timer
	_update_sprite()
	
	if is_end and get_parent() is InteractableSystem:
		get_parent().notify_system(active)  # deactivate it again, if it was already activated
	

func reached_by_energy_ball():  # called by previous pillar on you
	energy_ball.global_position = global_position 
	active = true
	if is_end and (get_parent() is InteractableSystem):  # notify system (door or trap)
		get_parent().notify_system(active)
	timer = die_down_time  # init your timer
	_update_sprite()
	# save globally
	Globals.interactable_states[get_path()] = active
	

func send_energy_ball():
	active = false
	is_sending_energy_ball = true
	energy_ball_progress = 0
	energy_ball.scale = Vector2(1, 1)  # reset size, when player managed to send it on
	if is_start:  # energy ball respawns
		active = true
	_update_sprite()
	AudioManager.create_audio(SoundEffect.SOUND_EFFECT_TYPE.LEVER_CHANGE_STATE)
	AudioManager.create_audio(SoundEffect.SOUND_EFFECT_TYPE.FIREBALL)
	# save globally
	Globals.interactable_states[get_path()] = active

func _update_sprite():
	if (active or is_sending_energy_ball) and not is_end:  # the end is placed inside the door.
		energy_ball.visible = true # doesnt change sprite, but sends off the energy ball
	else:
		energy_ball.visible = false
