class_name Player extends Entity

@export var dash_base_cd: float = 0.2

@onready var player_sprite :AnimatedSprite2D = $PlayerSprite
@onready var mask_sprite : Sprite2D  = $PlayerSprite/MaskSprite

var dash_active := false
var dash_cd_timer := 0.0

var mask_start_time = 10
var mask_time_remaining := 15.0

var closest_mask_drop: MaskDrop
var last_mask_drop : MaskDrop
const INTERACT_DIST = 100.0

var dead = false

func _ready() -> void:
	health_changed.connect(EventBus.health_changed.emit)
	health_changed.emit(health)
	equip_mask(current_mask_data)

func _process(delta: float) -> void:
	super._process(delta)
	if Input.is_action_pressed("attack"):
		use_mask(get_global_mouse_position())

func _physics_process(delta: float) -> void:
	if dead: return
	var input_vector := Input.get_vector("move_left", "move_right", "move_up", "move_down")
	
	if input_vector != Vector2.ZERO:
		velocity += input_vector * move_speed
	
	dash_cd_timer -= delta
	if dash_cd_timer > 0:
		collision_mask = (0xFFFF ^ 8) & collision_mask
	else:
		collision_mask = 8 | collision_mask

	if Input.is_action_just_pressed("dash") and dash_cd_timer <= 0:
		start_dash(input_vector)

	_handle_mask_durability(delta)

	_check_items()
	
	super._physics_process(delta)

func die():
	if dead: return
	super.die()
	dead = true
	visible = false

func revive():
	if not dead: return
	dead = false
	visible = true

func damage(amount: int = 1) -> void:
	EventBus.player_dmg.emit()
	super.damage(amount)

func start_dash(dir: Vector2):
	dash_active = true
	dash_cd_timer = dash_base_cd
	velocity += dir * move_speed * 40

	var tween = create_tween()
	tween.tween_property(player_sprite, "scale:x", 0.5, 0.1)
	tween.tween_property(player_sprite, "scale:x", 1, 0.1)

func _input(event: InputEvent) -> void:

	if event.is_action_pressed("interact") and closest_mask_drop:
		collect_drop(closest_mask_drop)

func equip_mask(mask_data : MaskData):
		current_mask_data = mask_data
		mask_sprite.texture = mask_data.texture
		EventBus.mask_changed.emit(mask_data.mask_name)


func collect_drop(drop_node : MaskDrop):
	if drop_node.has_method("collect"):
		drop_node.collect(global_position)
		
		current_mask_data = drop_node.mask_type 
		mask_time_remaining = mask_start_time
		equip_mask(drop_node.mask_type)

func _handle_mask_durability(delta : float):
	if get_tree().get_node_count_in_group("enemy") > 0:
		mask_time_remaining -= delta
		if mask_time_remaining <= 0:
			#die()
			pass
		EventBus.mask_time_changed.emit(mask_time_remaining / mask_start_time)

func _check_items():
	var masks : Array[Node] = get_tree().get_nodes_in_group("mask")
	closest_mask_drop = null
	var min_dist := INF

	for mask : MaskDrop in masks:
		var dist := global_position.distance_to(mask.global_position)
		if dist < INTERACT_DIST + 10:
			min_dist = dist
			closest_mask_drop = mask

	if last_mask_drop and closest_mask_drop != last_mask_drop:
		last_mask_drop.hide_popup()
		
	if closest_mask_drop:
		if min_dist < INTERACT_DIST:
			closest_mask_drop.show_popup()
		else:
			closest_mask_drop.hide_popup()
		last_mask_drop = closest_mask_drop
