class_name Car
extends Area2D

const SKID_DISTANCE: float = 23.0

@export var speed: float = 50.0
@export var car_sprite: Sprite2D = null
@export var shadow_sprite: Sprite2D = null
@export var oncoming: bool:
	set=_set_flip
@export var collision_top: CollisionShape2D = null
@export var collision_bot: CollisionShape2D = null
@export var explosion: PackedScene = null
@export var kick_sound: AudioStream = null
@export var skidding_sound: AudioStream = null

var is_skidding: bool = false
var _start_x: float = 0
var _return_tween: Tween = null


func _ready() -> void:
	area_entered.connect(_on_area_entered)
	_start_x = global_position.x


func _on_area_entered(area: Area2D) -> void:
	if area is not Car:
		return

	var is_behind: bool = global_position.y > area.global_position.y + 18.0
	var speed_dif: float = absf(speed - area.speed)
	if absf(global_position.x - area.global_position.x) > 11.0:
		if speed_dif > 50.0:
			area.destroy()
			return
		if is_skidding:
			return
		if not is_behind:
			skid(global_position.x > area.global_position.x)
			_on_skidding()
		brake.call_deferred(speed / 2.0)
	else:
		if speed_dif > 25.0:
			area.destroy()
			return

		if is_behind:
			brake.call_deferred(10.0)
		else:
			PulseSound1.load_and_play(kick_sound)
			kick()


func _on_skidding() -> void:
	pass


func _set_flip(value: bool) -> void:
	oncoming = value
	car_sprite.flip_v = value
	shadow_sprite.flip_v = value


func brake(to_speed: float) -> void:
	var prev_speed: float = speed
	speed = to_speed
	var tween: Tween = get_tree().create_tween()
	tween.tween_property(self, ^"speed", prev_speed, 1.0)


func destroy() -> void:
	if explosion:
		var spawned: Node2D = explosion.instantiate()
		add_sibling(spawned)
		spawned.global_position = global_position
	queue_free()


func kick() -> void:
	pass


func return_to_road() -> void:
	pass


func set_car_rotation(direction: int) -> void:
	car_sprite.flip_h = true if direction < 0 else false
	car_sprite.frame_coords.y = 1 if direction else 0
	shadow_sprite.frame_coords.y = 1 if direction else 0
	shadow_sprite.flip_h = true if direction < 0 else false
	collision_top.position.x = 2.0 * direction
	collision_bot.position.x = 4.0 * -direction


func set_sprite(number: int) -> void:
	car_sprite.frame_coords.x = number
	shadow_sprite.frame_coords.x = number


func skid(to_right: bool) -> void:
	PulseSound1.load_and_play(skidding_sound)
	is_skidding = true
	set_car_rotation(-1 if to_right else 1)
	if _return_tween:
		_return_tween.kill()
	var tween: Tween = get_tree().create_tween()
	var final_pos: float = global_position.x + SKID_DISTANCE * (1 if to_right else -1)
	tween.tween_property(self, ^"global_position:x", final_pos, 0.4)
	tween.tween_callback(set_car_rotation.bind(0))
	tween.tween_property(self, ^"is_skidding", false, 0.0)
	await get_tree().create_timer(1.0).timeout
	if not PlayerManager.get_instance().is_finished:
		return_to_road()
