extends "res://scenes/game/entities/entity.gd"

@onready var rollTimer = $RollTimer
@onready var rollCooldownTimer = $RollCooldownTimer


@onready var interactionArea = $InteractionArea

@onready var healthBar = $Camera2D/CanvasLayer/Control/VBoxContainer/HBoxContainer/HealthBar
@onready var rollCooldownBar = $Camera2D/CanvasLayer/Control/VBoxContainer/HBoxContainer2/RollCooldownBar
@onready var moneyValueLabel = $Camera2D/CanvasLayer/Control/HBoxContainer/MoneyValue
@onready var objectValue = $Camera2D/CanvasLayer/Control/ObjectValues/ObjectMoneyValue
@onready var objectValues = $Camera2D/CanvasLayer/Control/ObjectValues
@onready var stormProgress = $Camera2D/CanvasLayer/Control/Storm/ProgressBar
@onready var stormUi = $Camera2D/CanvasLayer/Control/Storm
@onready var stormTimerDamage = $StormTimerDamage
@onready var sormwarningLabel = $Camera2D/CanvasLayer/Control/STORMWARNINGLabel


@onready var camera = $Camera2D

@onready var animation = $Camera2D/CanvasLayer/Control/ColorRect/AnimationPlayer

var rollSpeed = maxSpeed * 5

const rollCooldown = 5.0
const rollTime = 0.4

var rolling = false

var canRoll = true

var carrying = false
var object = null

var lastDirection : Vector2
var lastdirectionVector : Vector2

var shownStormProgress = false

func _ready():
	animation.play("Introduction")
	rollCooldownBar.min_value = 0
	rollCooldownBar.max_value = rollCooldown
	healthBar.min_value = 0
	healthBar.max_value = health
	
func setHudValues():
	rollCooldownBar.value = rollCooldownTimer.time_left
	healthBar.value = health
	moneyValueLabel.text = str(G.money)
	if object != null:
		objectValues.show()
		objectValue.text = str(object.getValue())
	else:
		objectValues.hide()
	G.setLastHealth(health)
	stormProgress.value = G.StormTimeLeft
	if G.isStormThreshold():
		if not shownStormProgress:
			sormwarningLabel.show()
			shownStormProgress = true
			animation.play("StormTimerAppear")
		stormProgress.max_value = G.getStormThreshold()
	

func _physics_process(delta: float) -> void:
	Storm()
	setHudValues()
	var direction : Vector2 = Input.get_vector("MOVE_LEFT", "MOVE_RIGHT", "MOVE_UP", "MOVE_DOWN").normalized()
	#var direction : Vector2 = Vector2(
		#Input.get_action_strength("MOVE_RIGHT") - Input.get_action_strength("MOVE_LEFT"),
		#Input.get_action_strength("MOVE_DOWN") - Input.get_action_strength("MOVE_UP")
	#)
	var directionVector : Vector2 = position.direction_to(position + direction)

	if direction != Vector2.ZERO and not rolling:
		lastDirection = direction
		lastdirectionVector = directionVector
	if Input.is_action_just_pressed("ROLL") and lastDirection != Vector2.ZERO:
		roll()
	#if Input.is_action_just_pressed("DOOR"):
		#openDoor()
	if Input.is_action_just_pressed("Pickup"):
		match carrying:
			false:

					pickup(getNearestObject(interactionArea.get_overlapping_areas()))
			true:
				dropObject()
		#pickupArea.get_overlapping_areas()[0].pickup(self)
		#print(pickupArea.get_overlapping_areas())
	
	
	if rolling:
		move(lastdirectionVector * speed, acceleration)
	else:
		move(directionVector * speed, acceleration)
	setAnimation()
	move_and_slide()

func move(newVelocity : Vector2, acc):
	velocity.x = move_toward(velocity.x, 
		newVelocity.x, 
		acc)
	velocity.y = move_toward(velocity.y, 
		newVelocity.y, 
		acc)

func roll():
	if not rolling and canRoll: 
		dropObject()
		canRoll = false
		setSpeed(rollSpeed)
		invincible = true
		rolling = true
		rollTimer.start(rollTime)

func setAnimation():
	if not rolling:
		if Input.is_action_pressed("MOVE_LEFT") and not Input.is_action_pressed("MOVE_RIGHT") and animatedSprite.animation != "LEFT":
			animatedSprite.play("SIDE")
			animatedSprite.flip_h = true
		elif Input.is_action_pressed("MOVE_RIGHT") and not Input.is_action_pressed("MOVE_LEFT") and animatedSprite.animation != "RIGHT":
			animatedSprite.play("SIDE")
			animatedSprite.flip_h = false
		elif Input.is_action_pressed("MOVE_UP") and not Input.is_action_pressed("MOVE_DOWN") and animatedSprite.animation != "UP" and not Input.is_action_pressed("MOVE_LEFT") and not Input.is_action_pressed("MOVE_RIGHT"):
			animatedSprite.play("UP")
		elif Input.is_action_pressed("MOVE_DOWN") and not Input.is_action_pressed("MOVE_UP") and animatedSprite.animation != "DOWN" and not Input.is_action_pressed("MOVE_LEFT") and not Input.is_action_pressed("MOVE_RIGHT"):
			animatedSprite.play("DOWN")
		elif not animatedSprite.animation == "Ball" and not (Input.is_action_pressed("MOVE_UP") or Input.is_action_pressed("MOVE_RIGHT") or Input.is_action_pressed("MOVE_DOWN") or Input.is_action_pressed("MOVE_LEFT")):
			animatedSprite.play("IDLE")
			animatedSprite.flip_h = false
	elif animatedSprite.animation != "Ball":
		animatedSprite.play("Ball")

func _on_roll_timeout() -> void:
	animatedSprite.play_backwards("Ball")
	resetSpeed()
	invincible = false
	rolling = false
	rollCooldownTimer.start(rollCooldown)
	


func _on_roll_cooldown_timer_timeout() -> void:
	canRoll = true

func pickup(newObject):
	if newObject != null and newObject.is_in_group("Object"):
		if newObject.player == null and not rolling:
			carrying = true
			object = newObject
			speed -= object.getWeight()
			object.pickup(self)

func dropObject():
	if carrying:
		carrying = false
		object.drop()
		object = null
		resetSpeed()

func getNearestObject(list):
	var nearestObject = null
	var shortestDistance = 0
	if list != []:
		for i in list:
			if i.is_in_group("Object"):
				if nearestObject == null:
					shortestDistance = global_position.distance_to(i.global_position)
					nearestObject = i
				elif shortestDistance > global_position.distance_to(i.global_position):
					shortestDistance = global_position.distance_to(i.global_position)
					nearestObject = i
	return nearestObject


func openDoor():
	for door in interactionArea.get_overlapping_areas():
		if door.is_in_group("Door"):
			door.get_parent().toggle()

func _on_hit_box_signal_hit(damage: Variant) -> void:
	hit(damage)
	camera.shake(2,0.5)


func _on_animation_player_animation_finished(anim_name: StringName) -> void:
	if anim_name == "StormTimerAppear":
		animation.play("StormTimer")

func Storm():
	if G.StormTimeLeft <= 0 and stormTimerDamage.is_stopped():
		stormTimerDamage.start(1)

func _on_storm_timer_damage_timeout() -> void:
	if stormTimerDamage.is_stopped():
		stormTimerDamage.start(1)
		hit(1)

func pause():
	get_parent().pause()

func resume():
	get_parent().resume()
