extends CharacterBody2D

class_name Astronaut

@onready var anims := $AnimatedSprite2D
@onready var state_machine := $StateMachine
@onready var clean_shape := $CleanStaticBody/CollisionShape2D

@onready var check_satellite_timer := $CheckSatelliteTimer

@onready var terror_timer := $TerrorTimer

@onready var label := $Label

@onready var select_sprite := $Select
@onready var big_scare := $BigScare
@onready var small_scare := $SmallScare

var cadaver_scene := load("res://utils/cadaver.tscn")

const base_movement_speed := 70.0
const base_clean_speed := 200.0

enum STAT_TYPES {
	MVMT_SPEED,
	CLEAN_SPEED,
	ARMOR
}

var equipment := []
var weapon_type := Equipment.TYPE.SPONGE

var stats := [base_movement_speed, 1.0, 0]
var stress_modifier := 1.0

var target := Vector2.ZERO
var go_clean := false

var mouse_in := false
var satellite : Satellite = null 
var panel : SolarPanel = null

var call_sign := "TEST"
var anim_type := "TEST"

var current_dir_str := "up"

### 	 ACCESSORS 	 ###






### 	 BUILT-IN 	 ###

func _ready() -> void:
	state_machine.set_state("Idle")
	update_equipment()
	label.text = call_sign


func _physics_process(delta: float) -> void:
	state_machine.update(delta)



### 	 VIRTUAL 	 ###





### 	 LOGIC 	 ###

func update_equipment() -> void:
	for eq in equipment:
		match (eq.stat_type):
			STAT_TYPES.MVMT_SPEED:
				stats[eq.stat_type] = eq.modifiers[eq.stat_type] * base_movement_speed
			STAT_TYPES.CLEAN_SPEED:
				stats[eq.stat_type] = eq.modifiers[eq.stat_type]
			STAT_TYPES.ARMOR:
				stats[eq.stat_type] = eq.modifiers[eq.stat_type]

func select() -> void:
	state_machine.set_state("Selected")


func unselect() -> void:
	state_machine.set_state("Idle")


func set_target(_target : Vector2, _go_clean : bool = false) -> void:
	target = _target
	go_clean = _go_clean
	if go_clean:
		clean_shape.set_deferred("disabled", false)
	state_machine.set_state("Move")


func get_state_name() -> String:
	return state_machine.get_state_name() 


func set_state(state_name : String) -> void:
	state_machine.set_state(state_name)


func leave_satellite() -> void:
	if satellite:
		satellite.cleaners.erase(self)
		satellite = null
	if panel:
		panel.remove_cleaner()
		panel = null


func die() -> void:
	GLOBALS.selected.erase(self)
	GLOBALS.selectables.erase(self)
	leave_satellite()
	var crew_dict = null
	for c in GLOBALS.crew:
		if c.call_sign == call_sign:
			GLOBALS.used_call_signs.erase(call_sign)
			crew_dict = c
	GLOBALS.crew.erase(crew_dict)
	var cadaver = cadaver_scene.instantiate()
	cadaver.global_position = self.global_position
	EVENTS.cadaver_spawned.emit(cadaver)
	self.queue_free()


func terrorize(source_pos :Vector2, debris : bool = true) -> void:
	var max_source_dist := 30.0
	var dist := (self.global_position - source_pos).length()
	var ratio := dist/max_source_dist
	if !debris:
		max_source_dist = 110
		ratio = dist/max_source_dist
	stress_modifier = 1 - ratio
	terror_timer.start(ratio * 3)
	if ratio < 0.5:
		small_scare.set_deferred("visible", true)
	else:
		big_scare.set_deferred("visible", true)
	if panel:
		panel.update_stress_level()


func get_dir_string(dir : Vector2) -> String:
	var dir_string := ""
	if abs(dir.y) < 0.1:
		pass
	elif dir.y > 0:
		dir_string += "down"
	else:
		dir_string += "up"
	if abs(dir.x) < 0.1:
		pass
	elif dir.x > 0:
		dir_string += "right"
	else:
		dir_string += "left"
	if !dir_string.is_empty():
		current_dir_str = dir_string
		return dir_string
	return current_dir_str


### 	 SIGNAL-RESPONSE 	 ###

func _on_mouse_entered() -> void:
	mouse_in = true
	GLOBALS.selectables.append(self)


func _on_mouse_exited() -> void:
	mouse_in = false
	GLOBALS.selectables.erase(self)


func _on_check_satellite_timer_timeout() -> void:
	if satellite:
		if !satellite.clean:
			satellite._on_body_entered(self)
		else:
			leave_satellite()
				


func _on_death_area_2d_body_entered(body: Node2D) -> void:
	die()


func _on_terror_timer_timeout() -> void:
	big_scare.set_deferred("visible", false)
	small_scare.set_deferred("visible", false)
	stress_modifier = 1.0
