extends CharacterBody2D

@export var speed := 75.0
@export var gravity := 980.0
@export var max_health := 3
@export var attack_range := 40.0
@export var memory_piece_scene: PackedScene
@export var memory_texture: Texture2D
@export var memory_return_spawn: Marker2D
@export var memory_wardrobe: Node2D

@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
@onready var detection_area: Area2D = $DetectionArea
@onready var attack_hitbox = $AttackHitbox


var health := 3
var player: Player = null
var is_dead := false
var is_hurt := false
var is_attacking := false
var attack_cooldown := false
var knockback_velocity := Vector2.ZERO

func _ready() -> void:
	health = max_health
	attack_hitbox.monitoring = false
	sprite.play("idle")

	detection_area.body_entered.connect(_on_detection_body_entered)
	detection_area.body_exited.connect(_on_detection_body_exited)

	sprite.animation_finished.connect(_on_animation_finished)

func _physics_process(delta: float) -> void:
	if is_dead:
		return

	if not is_on_floor():
		velocity.y += gravity * delta

	if is_hurt:
		velocity = knockback_velocity

		knockback_velocity = knockback_velocity.move_toward(
			Vector2.ZERO,
			800 * delta
		)

		move_and_slide()
		return

	if is_attacking:
		velocity.x = 0
		move_and_slide()
		return

	if player:
		var direction := player.global_position.x - global_position.x

		if abs(direction) > attack_range:
			velocity.x = sign(direction) * speed
			sprite.play("walk")

			if velocity.x < 0:
				sprite.flip_h = true
			elif velocity.x > 0:
				sprite.flip_h = false
		else:
			velocity.x = 0
			attack()
	else:
		velocity.x = move_toward(velocity.x, 0, speed)
		sprite.play("idle")

	move_and_slide()

func attack() -> void:
	if is_attacking:
		return
	if attack_cooldown:
		return
	is_attacking = true
	attack_cooldown = true
	velocity.x = 0
	sprite.play("attack")
	
	await get_tree().create_timer(0.2).timeout
	
	do_attack_damage()

func do_attack_damage() -> void:
	print("Checking attack hit")

	attack_hitbox.monitoring = true
	await get_tree().physics_frame
	await get_tree().physics_frame

	var bodies = attack_hitbox.get_overlapping_bodies()
	print("Bodies found: ", bodies.size())

	for body in bodies:
		if body is Player:
			print("PLAYER HIT")
			body.playerTakesDamage(1)

	attack_hitbox.monitoring = false

func take_damage(amount: int = 1) -> void:
	if is_dead:
		return

	health -= amount
	print("Skeleton health:", health)

	if health <= 0:
		die()
	else:
		is_hurt = true

		if player:
			var knockback_direction = sign(global_position.x - player.global_position.x)
			knockback_velocity = Vector2(knockback_direction * 125, 0)

		sprite.play("hurt")

		await get_tree().create_timer(0.3).timeout
		is_hurt = false
		knockback_velocity = Vector2.ZERO

func die() -> void:
	if is_dead:
		return

	is_dead = true
	velocity.x = 0
	sprite.play("death")
	print("Skeleton died")

func _on_detection_body_entered(body: Node) -> void:
	if body is Player:
		player = body
		print("Skeleton detected player")

func _on_detection_body_exited(body: Node) -> void:
	if body == player:
		player = null
		print("Skeleton lost player")

func _on_animation_finished() -> void:
	if sprite.animation == "hurt":
		is_hurt = false
		knockback_velocity = Vector2.ZERO

	if sprite.animation == "attack":
		is_attacking = false
		await get_tree().create_timer(1.0).timeout
		attack_cooldown = false
	
	if sprite.animation == "death":
		if memory_piece_scene:
			var piece = memory_piece_scene.instantiate()
			get_parent().add_child(piece)
			piece.global_position = global_position

			piece.memory_texture = memory_texture
			piece.return_spawn = memory_return_spawn
			piece.wardrobe = memory_wardrobe

		queue_free()
