class_name ProjectileLightning
extends ProjectileBase

@export var line_width: float = 2
@onready var lightning: Array = get_children()

# Add variables to track collision state
var has_collided: bool = false
var collision_point: Vector2 = Vector2.ZERO

func _init() -> void:
	#super._init()
	Log.pr("ProjectileLightning _init")

func _ready():
	Log.pr(ignore_target)

	lifetime_timer = Timer.new()
	add_child(lifetime_timer)
	lifetime_timer.one_shot = true
	lifetime_timer.wait_time = lifetime
	lifetime_timer.connect("timeout", _on_lifetime_timeout)
	lifetime_timer.start()
	
	# Make sure we have a collision shape
	ensure_collision_shape()
	
	for child in lightning:
		if child.has_method("set_line_width"):
			child.set_line_width(line_width)
	
	emit_signal("on_spawned", self)
	connect("body_entered", _on_body_entered)

# Add a method to ensure we have a collision shape
func ensure_collision_shape():
	# Check if we already have a collision shape
	var has_collision_shape = false
	var existing_shape = null
	
	for child in get_children():
		if child is CollisionShape2D:
			has_collision_shape = true
			existing_shape = child
			break
	
	# If no collision shape exists, create one
	if not has_collision_shape:
		var collision_shape = CollisionShape2D.new()
		var capsule_shape = CapsuleShape2D.new()
		
		# Set the shape properties
		capsule_shape.radius = line_width / 2
		collision_shape.shape = capsule_shape
		
		add_child(collision_shape)
		existing_shape = collision_shape
		
		# Make sure the lightning area is set to detect the right objects
		set_collision_mask_value(2, true) # Assuming layer 2 is for enemies
		set_collision_mask_value(3, true) # Assuming layer 3 is for objects
	
	# Update the collision shape dimensions and position
	update_collision_shape(existing_shape)

# Combined method to update collision shape based on current state
func update_collision_shape(collision_shape = null):
	if collision_shape == null:
		# Find the collision shape if not provided
		for child in get_children():
			if child is CollisionShape2D:
				collision_shape = child
				break
	
	if collision_shape:
		var capsule = collision_shape.shape as CapsuleShape2D
		if capsule:
			var target = collision_point if has_collided else target_position
			var distance = global_position.distance_to(target)
			var dir = (target - global_position).normalized()
			
			# Update capsule height to match exact distance
			capsule.height = distance
			
			# Fix rotation based on current direction
			collision_shape.rotation = dir.angle() + PI / 2
			
			# Fix position: Move the shape so it starts at origin
			collision_shape.position = dir * (distance / 2)
		

func _process(delta):
	# Update target positions for lightning bolts
	for child in lightning:
		if child is LightningBolt:
			child.goal_point = collision_point if has_collided else target_position

	# Update collision shape if it exists
	update_collision_shape()

# Implement the body_entered signal handler
func _on_body_entered(body):
	if ignore_target.has(body):
		Log.pr("Ignoring body: ", body.name)
		return

	# Check if the colliding body is an enemy or object
	if body.is_in_group("enemies") or body.is_in_group("objects"):
		if not has_collided: # Only process the first collision
			# Set collision state and point
			has_collided = true
			
			# Calculate the collision point
			var direction_to_body = (body.global_position - global_position).normalized()
			var body_radius = 10.0 # Adjust for your game
			collision_point = body.global_position - (direction_to_body * body_radius)
			
			# Debug output
			Log.pr("Lightning hit: " + body.name + " at point: " + str(collision_point))
			
			# IMPORTANT: Immediately update the collision shape to stop at collision point
			update_collision_shape()

			_trigger_explosion()

		#super._on_body_entered(body)

			
	if body.is_in_group("enemies") and is_friendly:
		Log.pr("Hit enemy: ", body.name)
		# Deal damage to enemy
		if body.has_method("take_damage"):
			body.take_damage(damage)
		
	# Emit signal for modifiers to react to
	emit_signal("on_hit", self, body)
		
	# Handle piercing
	if pierce_count > 0:
		pierce_count -= 1
	else:
		# Handle explosive impact
		if has_explosive_impact:
			# Store the target that triggered the explosion
			ignore_target.append(body)
			_trigger_explosion()

func _spawn_explosion_projectiles():
	for i in range(explosion_projectile_count):
		# Create a new projectile
		Log.pr("Spawning explosion projectile")
		var new_proj = (load(scene_file_path) as PackedScene).instantiate()
		Log.pr("New projectile: ", new_proj)
		new_proj.global_position = collision_point
   
		var min_distance = 50
		var max_distance = 125

		# Generate a random angle
		var max_target_distance = 200 # Maximum distance to look for enemies

		# Get all enemies in the scene
		var potential_targets = get_tree().get_nodes_in_group("enemies")
		var valid_targets = []

		# Filter enemies to only include ones within range
		for enemy in potential_targets:
				var distance = enemy.global_position.distance_to(collision_point)
				if distance <= max_target_distance:
						valid_targets.append(enemy)

		var random_point = Vector2.ZERO

		# Check if we have any valid targets
		if valid_targets.size() > 0:
				# Pick a random enemy from valid targets
				var random_enemy = valid_targets[randi() % valid_targets.size()]
				random_point = random_enemy.global_position
		else:
				# Fallback if no enemies in range - use the original random point logic
				var random_angle = randf_range(0, TAU)
				var random_distance = randf_range(50, max_target_distance)
				random_point = collision_point + Vector2(
						cos(random_angle) * random_distance,
						sin(random_angle) * random_distance
				)

		new_proj.target_position = random_point

		new_proj.damage = damage * explosion_projectile_damage_mult
		new_proj.speed = explosion_projectile_speed
		
		# Clear explosive properties so we don't get infinite loops
		new_proj.has_explosive_impact = true
		new_proj.explosion_projectile_count = 1
		
		# Pass the ignore_target to the new projectiles
		new_proj.ignore_target = ignore_target

		Log.pr("New projectile: ", new_proj)
		
		# Add to scene tree
		get_tree().root.call_deferred("add_child", new_proj)

func _on_lifetime_timeout():
	Log.pr("ProjectileLightning _on_lifetime_timeout")
	super._on_lifetime_timeout()
