extends CharacterBody2D
@onready var line: Line2D = $Line2D
@onready var red_texture: Texture2D = preload("res://assets/tile2.png")
@onready var green_texture: Texture2D = preload("res://assets/tile1.png")
@onready var planer_texture: Texture2D = preload("res://assets/yellow_plane2x.png")
@onready var planey_texture: Texture2D = preload("res://assets/yellow_plane2.png")

const SPEED = 300.0
const JUMP_VELOCITY = -400.0
func _ready():
	line.clear_points()
	$CollisionPolygon2D/AnimationPlayer.stop()
	$"../planes/box1".visible=false
	$"../planes/bomb1".visible=false
	
func _input(event):
	if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
		var plane2 = find_sprite_2d($"../planes/YellowPlane2")
		var plane3 = find_sprite_2d($"../planes/YellowPlane3")
		#print("Plane2 is at pos : "+str(plane2.global_position))
		var click_pos: Vector2 = get_global_mouse_position()
		draw_line_to(click_pos)
		$CollisionPolygon2D/AudioStreamPlayer.play()
		$"../GPUParticles2D".position=click_pos
		if abs(click_pos.x-plane2.global_position.x)<100 and abs(click_pos.y-plane2.global_position.y)<50:
			plane2.texture=planer_texture
			await get_tree().create_timer(0.9).timeout
			plane2.texture=planey_texture
		if abs(click_pos.x-plane3.global_position.x)<100 and abs(click_pos.y-plane3.global_position.y)<50:
			plane3.texture=planer_texture
			await get_tree().create_timer(0.9).timeout
			plane3.texture=planey_texture
		
		await get_tree().create_timer(0.4).timeout
		if is_click_on_static_body(click_pos):
			#print(await which_click_on_static_body(click_pos))
			await which_click_on_static_body(click_pos)
			
			
func is_click_on_static_body(world_pos: Vector2) -> bool:
	var space := get_world_2d().direct_space_state

	var query := PhysicsPointQueryParameters2D.new()
	query.position = world_pos
	query.collide_with_bodies = true
	query.collide_with_areas = false

	var result := space.intersect_point(query)

	for hit in result:
		if hit.collider is StaticBody2D:
			return true

	return false


func find_sprite_2d(node: Node) -> Sprite2D:
	if node is Sprite2D:
		return node

	for child in node.get_children():
		var result := find_sprite_2d(child)
		if result:
			return result

	return null

func get_static_body_positions(root: Node) -> Array[Vector2]:
	var positions: Array[Vector2] = []

	if root is StaticBody2D and root.name.begins_with("StaticBody2D"):
		positions.append(root.global_position)

	for child in root.get_children():
		positions.append_array(get_static_body_positions(child))

	return positions

# Returns all points that are roughly in the same Y-plane as hit_pos (within delta_y)
# and are located to the right (x > hit_pos.x)
func get_points_right_of_hit_in_y_plane(hit_pos: Vector2, points: Array, delta_y: float = 4.0) -> bool:
	var result: Array = []

	for pos in points:
		# 1️⃣ Check if Y is within delta
		if abs(pos.y - hit_pos.y) <= delta_y:
			# 2️⃣ Check if X is to the right of hit
			if pos.x > hit_pos.x:
				#result.append(pos)
				return true

	#return result
	return false
	

func get_points_left_of_hit_in_y_plane(hit_pos: Vector2, points: Array, delta_y: float = 4.0) -> bool:
	var result: Array = []

	for pos in points:
		# 1️⃣ Check if Y is within delta
		if abs(pos.y - hit_pos.y) <= delta_y:
			# 2️⃣ Check if X is to the right of hit
			if pos.x < hit_pos.x:
				#result.append(pos)
				return true

	#return result
	return false



func which_click_on_static_body(world_pos: Vector2) -> StringName:
	var space := get_world_2d().direct_space_state
	var positions := get_static_body_positions(get_tree().current_scene)
	
	positions.sort_custom(func(a: Vector2, b: Vector2) -> bool:
		return a.y < b.y
	)

	var query := PhysicsPointQueryParameters2D.new()
	query.position = world_pos
	query.collide_with_bodies = true
	query.collide_with_areas = false

	var result := space.intersect_point(query)

	for hit in result:
		if hit.collider is StaticBody2D:
			var sprite := find_sprite_2d(hit.collider)
			if sprite:
				var old_pos = hit.collider.position

				sprite.texture = red_texture
				await get_tree().create_timer(0.4).timeout
				sprite.texture = green_texture
				
				#if blocks are on the right and character is on the right
				if !get_points_right_of_hit_in_y_plane(old_pos, positions) and $".".position.x>old_pos.x:
					print(
					"Hit position is " + str(old_pos)
					+ " can be shot or not right: "
					+ str(!get_points_right_of_hit_in_y_plane(old_pos, positions))
				)
					await get_tree().create_timer(0.4).timeout
					sprite.texture = green_texture

					# presuň až nakoniec
					hit.collider.position = Vector2(
						randi_range(-5000, -4000),
						randi_range(-5000, -4000)
					)
				#if blocks are on the left and character is on the left
				if !get_points_left_of_hit_in_y_plane(old_pos, positions) and $".".position.x<old_pos.x:
					print(
					"Hit position is " + str(old_pos)
					+ " can be shot or not left: "
					+ str(!get_points_left_of_hit_in_y_plane(old_pos, positions))
				)
					await get_tree().create_timer(0.4).timeout
					sprite.texture = green_texture

					# presuň až nakoniec
					hit.collider.position = Vector2(
						randi_range(-5000, -4000),
						randi_range(-5000, -4000)
					)

			return hit.collider.name

	return ""


func draw_line_to(target_pos: Vector2):
	line.clear_points()
	line.add_point(Vector2.ZERO) # pozícia CharacterBody2D
	line.add_point(to_local(target_pos))

#kick animation after packet or bomb
func rotate_once(body: CharacterBody2D, duration: float = 1.0) -> void:
	var tween := body.create_tween()
	tween.tween_property(
		body,
		"rotation",
		body.rotation + TAU,
		duration
	).set_trans(Tween.TRANS_LINEAR).set_ease(Tween.EASE_IN_OUT)


var k=-1 #switching planes direction
var v=0
var v2=0 #visibile box or bomb
var c=0
var c2=0 #counters of playback on bomb box
var ba=0 #bomb attack
var ba2=0
func _physics_process(delta: float) -> void:
	if abs($"../planes/bomb1".global_position.x-$"../CharacterBody2D".position.x)<70 and abs($"../planes/bomb1".global_position.y-$"../CharacterBody2D".position.y)<70:
		ba=1
		rotate_once($"../CharacterBody2D",0.6)
	if !$"../AudioStreamPlayer".has_stream_playback() and ba==1:
		$"../AudioStreamPlayer".play()
		$"../Energybar1".scale.x*=0.95
		ba=0
		$"../planes/bomb1".global_position.y+=1000
	if abs($"../planes/box1".global_position.x-$"../CharacterBody2D".position.x)<70 and abs($"../planes/box1".global_position.y-$"../CharacterBody2D".position.y)<70:
		ba2=1
		rotate_once($"../CharacterBody2D",0.6)
	if !$"../AudioStreamPlayer2".has_stream_playback() and ba2==1:
		$"../AudioStreamPlayer2".play()
		if $"../Energybar1".scale.x<=1:
			$"../Energybar1".scale.x*=1.05
		ba2=0
		$"../planes/box1".global_position.y+=1000
		
	$"../planes".position.x+=delta*300*k
	if $"../planes".position.x<-2500:
		k=1
		$"../planes/YellowPlane2".flip_h=true
		$"../planes/YellowPlane3".flip_h=true
	if $"../planes".position.x>2500:
		k=-1
		$"../planes/YellowPlane2".flip_h=false
		$"../planes/YellowPlane3".flip_h=false
	
	if [1,2,3,4,5,6,7].pick_random()==7 and v!=1:
		$"../planes/box1".global_position.x=$"../planes/YellowPlane2".global_position.x
		$"../planes/box1".global_position.y=$"../planes/YellowPlane2".global_position.y
		$"../planes/box1".visible=true
		v=1
	if v==1 and $"../planes/box1".global_position.y<1080:
		$"../planes/box1".global_position.y+=delta*250
		if !$"../planes/AudioStreamPlayer3".has_stream_playback() and c<1:
			$"../planes/AudioStreamPlayer3".play()
			c+=1
	else:
		$"../planes/box1".visible=false
		v=0
		c=0
		
	if [1,2,3,4,5,6,7].pick_random()==3 and v2!=1:
		$"../planes/bomb1".global_position.x=$"../planes/YellowPlane3".global_position.x
		$"../planes/bomb1".global_position.y=$"../planes/YellowPlane3".global_position.y
		$"../planes/bomb1".visible=true
		v2=1
	if v2==1 and $"../planes/bomb1".global_position.y<1080:
		$"../planes/bomb1".global_position.y+=delta*190
		if !$"../planes/AudioStreamPlayer2".has_stream_playback() and c2<1:
			$"../planes/AudioStreamPlayer2".play()
			c2+=1
	else:
		$"../planes/bomb1".visible=false
		v2=0
		c2=0
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta

	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var direction := Input.get_axis("ui_left", "ui_right")
	
	if direction==1.0:
		velocity.x = direction * SPEED
		$CollisionPolygon2D/AnimationPlayer.play("character1")
		$CollisionPolygon2D/Sprite2D.flip_h=true
	elif direction==-1.0:
		velocity.x = direction * SPEED
		$CollisionPolygon2D/AnimationPlayer.play("character1")
		$CollisionPolygon2D/Sprite2D.flip_h=false
	else:
		$CollisionPolygon2D/AnimationPlayer.stop()
		velocity.x = move_toward(velocity.x, 0, SPEED)

	move_and_slide()


func _on_timer_timeout() -> void:
	line.clear_points()
	$"../GPUParticles2D".position=Vector2(-500,-500)
