class_name Rock
extends CharacterBody2D

## ===== 配置 =====
@export var falling_gravity: float = 2000.0
@export var max_fall_speed: float = 3000.0
@export var kill_y: float = 10000000.0

@export var shake_x := 2.0
@export var shake_y := 2.0
@export var step_time := 0.034

@export var binded_rock_texture: Node2D

## ===== 常量 =====
const NO_TARGET_Y: float = 1e20

## ===== 状态 =====
var is_falling: bool = false
var fall_target_y: float = NO_TARGET_Y

## ===== 抖动量 =====
var _shake_tween: Tween
var _shake_origin_pos: Vector2

##岩石开始抖动
func start_shaking() -> void:
	var sprite := $Sprite2D
	
	if binded_rock_texture: sprite = binded_rock_texture
	if not sprite:
		return

	# 防止重复启动
	if _shake_tween and _shake_tween.is_running():
		return

	_shake_origin_pos = sprite.position

	_shake_tween = create_tween()
	_shake_tween.set_loops() # 无限循环
	_shake_tween.set_trans(Tween.TRANS_SINE)
	_shake_tween.set_ease(Tween.EASE_IN_OUT)

	# 左上 → 右下 → 左下 → 右上（循环更自然）
	_shake_tween.tween_property(
		sprite,
		"position",
		_shake_origin_pos + Vector2(-shake_x, -shake_y),
		step_time
	)
	_shake_tween.tween_property(
		sprite,
		"position",
		_shake_origin_pos + Vector2(shake_x, shake_y),
		step_time
	)
	_shake_tween.tween_property(
		sprite,
		"position",
		_shake_origin_pos + Vector2(-shake_x, shake_y),
		step_time
	)
	_shake_tween.tween_property(
		sprite,
		"position",
		_shake_origin_pos + Vector2(shake_x, -shake_y),
		step_time
	)

##岩石结束抖动
func stop_shaking() -> void:
	var sprite := $Sprite2D
	if not sprite:
		return

	if _shake_tween:
		_shake_tween.kill()
		_shake_tween = null

	# 强制回到原位，防止残留偏移
	sprite.position = _shake_origin_pos

## 开始下落（可指定目标）
func start_falling(target_y: float = NO_TARGET_Y) -> void:
	is_falling = true
	fall_target_y = target_y
	velocity = Vector2.ZERO


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

	_update_fall(delta)


func _update_fall(delta: float) -> void:
	## 速度积分
	velocity.y += falling_gravity * delta
	velocity.y = min(velocity.y, max_fall_speed)

	## 预测下一帧位置
	var next_y: float = global_position.y + velocity.y * delta

	## 到达目标 / kill
	var limit_y: float = min(fall_target_y, kill_y)
	if next_y >= limit_y:
		global_position.y = limit_y
		_on_fall_finished()
		return

	move_and_slide()

func _on_fall_finished() -> void:
	is_falling = false
	queue_free() # 或者变成平台 / 播动画
