extends Node
class_name GameManager

@onready var grace_period: Timer = $GracePeriod
@onready var event_timer: Timer = $EventTimer
@onready var vfx = $VFX
@onready var res_ev01 = load("res://events/event_01.tscn")
@onready var res_ev02 = load("res://events/event_02.tscn")
@onready var res_ev03 = load("res://events/event_03.tscn")
@onready var res_ev04 = load("res://events/event_04.tscn")
@onready var res_ev05 = load("res://events/event_05.tscn")
@onready var res_ev06 = load("res://events/event_06.tscn")
@onready var res_ev07 = load("res://events/event_07.tscn")
@onready var res_ev08 = load("res://events/event_08.tscn")
@onready var res_ev09 = load("res://events/event_09.tscn")
@onready var res_ev10 = load("res://events/event_10.tscn")
@onready var res_ev11 = load("res://events/event_11.tscn")
@export var spinner_deadzone: float = 15 # Bad placeholder value, PLEASE TEST & FINETUNE!
@export var text_typer: TextTyper

@export var dinamo: AudioStreamPlayer

var current_event: Node = null
var event_running: bool = false
var spinner_mechanic: bool = true
var dead_spinner: bool = false
var no_energy: bool = false
var spinner_speed: float = 0
var time_since_last_motion: float = 0

signal event_complete
signal event_fail
signal lights_out
signal lights_in
signal left_engine_on
signal left_engine_off
signal right_engine_on
signal right_engine_off

func _ready():
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _process(delta):
	time_since_last_motion += delta
	if (abs(spinner_speed) > 0 and time_since_last_motion >= .2):
		spinner_speed = 0
		#print(spinner_speed)
	if event_running:
		event_process()
		verify_event()
	if (abs(spinner_speed) < spinner_deadzone and !dead_spinner):
		grace_period.start()
		if dinamo:
			dinamo.volume_db = -80
		dead_spinner = true
	if (abs(spinner_speed) >= spinner_deadzone and dead_spinner):
		grace_period.stop()
		dead_spinner = false
		if dinamo:
			dinamo.volume_db = -10
		if (no_energy):
			lights_in.emit()
		no_energy = false
	feedbacks()
	# DEBUG STUFF - REMOVE FOR RELEASE
	if Input.is_action_just_pressed("DEBUG_Lock_Cursor"):
		Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	if Input.is_action_just_pressed("DEBUG_Unlock_Cursor"):
		Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

func _input(event):
	if event is InputEventMouseMotion:
		spinner_speed = event.get_relative().x
		#print(spinner_speed)
		time_since_last_motion = 0

func feedbacks():
	if Input.is_action_just_pressed("LJ_UP") or Input.is_action_just_pressed("LJ_DOWN") \
	or Input.is_action_just_pressed("LJ_LEFT") or Input.is_action_just_pressed("LJ_RIGHT"):
		left_engine_on.emit()
		print("left engine on")
	if Input.is_action_just_pressed("RJ_UP") or Input.is_action_just_pressed("RJ_DOWN") \
	or Input.is_action_just_pressed("RJ_LEFT") or Input.is_action_just_pressed("RJ_RIGHT"):
		right_engine_on.emit()
		print("right engine on")
	if Input.is_action_just_released("LJ_UP") or Input.is_action_just_released("LJ_DOWN") \
	or Input.is_action_just_released("LJ_LEFT") or Input.is_action_just_released("LJ_RIGHT"):
		left_engine_off.emit()
		print("left engine off")
	if Input.is_action_just_released("RJ_UP") or Input.is_action_just_released("RJ_DOWN") \
	or Input.is_action_just_released("RJ_LEFT") or Input.is_action_just_released("RJ_RIGHT"):
		right_engine_off.emit()
		print("right engine off")

# Change the current event to "n_event".
func insert_event(n_event: Node):
	current_event = n_event
	event_timer.wait_time = current_event.time
	event_running = true
	event_timer.start()
	print("time: " + str(event_timer.time_left))
	print(n_event.hold)
	print(n_event.press)
	print(n_event.shake)
	
	if text_typer:
		text_typer.animate_text_in(n_event.dialogue)

func check_if_held():
	if current_event.hold.is_empty():
		return true
	var hold_ok_target = current_event.hold_ok.size()
	var hold_ok_current = 0
	for check in current_event.hold_ok:
		if check == true:
			hold_ok_current += 1
	if hold_ok_current == hold_ok_target:
		return true
	else:
		return false
	
func verify_event():
	# Goals and progress.
	var press_ok_target = current_event.press_ok.size()
	var hold_ok_target = current_event.hold_ok.size()
	var shake_ok_target = current_event.shake_ok.size()
	var press_ok_current = 0
	var hold_ok_current = 0
	var shake_ok_current = 0
	# Verify arrays only if they're used.
	if !current_event.press_ok.is_empty():
		for check in current_event.press_ok:
			if check == true:
				press_ok_current += 1
	if !current_event.hold_ok.is_empty():
		for check in current_event.hold_ok:
			if check == true:
				hold_ok_current += 1
	if !current_event.shake_ok.is_empty():
		for check in current_event.shake_ok:
			if check <= 0:
				shake_ok_current += 1
				
	if press_ok_current == press_ok_target and hold_ok_current == hold_ok_target\
	and shake_ok_current == shake_ok_target:
		print("Success!")
		event_complete.emit()
		event_timer.stop()
		vfx.stop()
		vfx.play("RESET")
		event_running = false

func event_process():
	if !current_event.press.is_empty() and check_if_held():
		var i = 0
		for action in current_event.press:
			if Input.is_action_just_pressed(action):
				print(action + " was pressed")
				current_event.press_ok[i] = true
			i += 1
	if !current_event.hold.is_empty():
		var i = 0
		for action in current_event.hold:
			if Input.is_action_pressed(action):
				current_event.hold_ok[i] = true
			else:
				current_event.hold_ok[i] = false
			i += 1
	if !current_event.shake.is_empty() and check_if_held():
		for action in current_event.shake:
			if Input.is_action_just_pressed(action):
				current_event.shake_ok[0] -= 1
	if !current_event.shake_b.is_empty() and check_if_held():
		for action in current_event.shake_b:
			if Input.is_action_just_pressed(action):
				current_event.shake_ok[1] -= 1

func _on_grace_period_timeout():
	print("Lights out!")
	lights_out.emit()
	no_energy = true

func _on_event_timer_timeout():
	print("Failure!")
	event_fail.emit()
	vfx.stop()
	vfx.play("RESET")
	event_running = false
