extends CameraToolBasic
class_name ReedCameraFollowController

const _CONSTANTS := preload("res://addons/reedcamera/_data/CameraSystemConst.gd")
const _DEBUG_TOOL := preload("res://addons/reedcamera/scripts/camera_tools/DeadZoneDebug.tscn")

@export_group("Dead Zone")
@export var dead_zone_ratio : Vector2 = Vector2(.6,.6)

@export_group("Follow") 
@export var enabled_follow: bool = true 
@export var follow_speed: float = 600.0   # 世界单位 / 秒
@export var follow_lerp := 0.12 # 0~1，越大越“跟手”，越小越“蔚蓝感”的滞后
@export_subgroup("Follow Dynamic Speed")
@export var min_speed_scale := 0.4   # 贴近死区时
@export var max_speed_scale := 2.0   # 远离死区时
@export var max_offset_ratio := 1.0  # offset 达到 1 个 dead_zone 时为最大速率

##TODO:后续添加一下Runtime的修改逻辑
@export_group("Debug") 
@export var show_preview: bool = true
var _show_preview: bool = false:
	set(value):
		_update_debug(value)
		_show_preview = value
@export var preview_color: Color = Color.AQUAMARINE
@export var preview_line_width : float = 2.0

enum State{
	IDLE,
	CHASING,
	STATIC
}

## 用于描述和切换follower工具的状态
var _current_state: State = State.IDLE

##Follower工具绑定的followNode
var _follow_node2d : Node2D = null
##最终的位置
var _final_position: Vector2

##缓存全局系统
var _sys: Object = null
##缓存DebugTool
var _screen_ratio_rect_draw_tool: Node = null
##缓存camera
var _camera: Camera2D = null

func _ready() -> void:
	_show_preview = show_preview

func _process(delta: float) -> void:
	#print(_current_state)
	if _current_state == State.IDLE:
		return
	if _current_state == State.CHASING or State.STATIC:
		update_follow(delta)

func _update_debug(debug:bool) -> void:
	if debug:
		if _screen_ratio_rect_draw_tool:
			var t := _screen_ratio_rect_draw_tool.get_child(0)
			t.set_ratio(dead_zone_ratio)
			t.set_target_node(_follow_node2d)
			t.set_style(preview_color,preview_line_width)
			return
		else:
			var t := _DEBUG_TOOL.instantiate()
			self.add_child(t)
			_screen_ratio_rect_draw_tool = t
			
			t.get_child(0).set_ratio(dead_zone_ratio)
			t.get_child(0).set_target_node(_follow_node2d)
			t.get_child(0).set_style(preview_color,preview_line_width)
	else:
		if not _screen_ratio_rect_draw_tool:
			return
		else:
			_screen_ratio_rect_draw_tool.get_child(0).clear()

func update_follow(delta: float) -> void:
	if not enabled_follow:
		return
	if not _follow_node2d:
		return

	var cam := _get_camera_from_pointer()
	if not cam:
		return
	
	# 0. 读取相机的全局坐标
	_final_position = cam.global_position
	
	# 1. target 的屏幕坐标（Canvas Space）
	var t_in_screen :Vector2 = \
		_follow_node2d.get_global_transform_with_canvas().get_origin()
	
	var screen_size : Vector2 = _get_camera_system().get_screen_size()
	var screen_center : Vector2 = screen_size * 0.5
	var dead_half : Vector2 = screen_size * dead_zone_ratio * 0.5
	
	# 2. 获得移动方向
	var offset := \
		_compute_deadzone_offset(
			t_in_screen,
			screen_center,
			dead_half
		)
	
	if offset == Vector2.ZERO:
		_current_state = State.STATIC
		return
	_current_state = State.CHASING
	
	
	#var move_dir := offset.normalized()
	#var world_velocity := (move_dir * follow_speed) / cam.zoom
	
	var offset_len := offset.length()
	var dead_len := dead_half.length()

	# 0~1 的距离比例
	var t := clamp(offset_len / (dead_len * max_offset_ratio), 0.0, 1.0)

	# 距离越远，速度越快
	var speed_scale := lerp(min_speed_scale, max_speed_scale, t)

	var move_dir := offset.normalized()
	var world_velocity : Vector2 = (move_dir * follow_speed * speed_scale) / cam.zoom
	
	var desired_pos := _final_position + world_velocity * delta

	if follow_lerp > 0.0:
		_final_position = cam.global_position.lerp(desired_pos, follow_lerp)
	else:
		_final_position = desired_pos

func _compute_deadzone_offset(
	screen_pos: Vector2,
	screen_center: Vector2,
	dead_half: Vector2
) -> Vector2:
	var o := Vector2.ZERO
	var dx := screen_pos.x - screen_center.x
	var dy := screen_pos.y - screen_center.y

	if dx < -dead_half.x:
		o.x = dx + dead_half.x
	elif dx > dead_half.x:
		o.x = dx - dead_half.x

	if dy < -dead_half.y:
		o.y = dy + dead_half.y
	elif dy > dead_half.y:
		o.y = dy - dead_half.y

	return o

## 从相机指针获取相机组件
func _get_camera_from_pointer() -> Camera2D: 
	if _camera:
		return _camera
	
	var p := get_parent() 
	if p and p.has_method("get_camera"): 
		_camera = p.get_camera() as Camera2D 
		return _camera
	
	return _camera

## 获取全局相机管理器
func _get_camera_system() -> Object:
	if _sys:
		return _sys
	
	if Engine.has_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME):
		_sys = Engine.get_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME)
	
	return _sys


##外部调用，设置一个相机系统的跟随者
func register_follower(follower: Node2D) -> void:
	_follow_node2d = follower
	if self._current_state == State.IDLE:
		start_follow()

##外部调用，移除一共相机系统的跟随者
func unregister_follower() -> void:
	_follow_node2d = null
	stop_follow()

##外部调用，开始跟随
func start_follow() -> void:
	_current_state = State.STATIC

##外部调用，结束跟随
func stop_follow() -> void:
	_current_state = State.IDLE

func get_base_position() -> Vector2:
	return _final_position

func has_base_position() -> bool:
	return _current_state == State.CHASING
