extends Node

var music_player: AudioStreamPlayer
var ambient_loop: AudioStreamPlayer
var whale_player: AudioStreamPlayer

var _whale_timer: Timer
var _music_tween: Tween

const MUSIC_PATH := "res://audio/music/"
const SFX_PATH := "res://audio/sfx/"

func _ready() -> void:
	music_player = AudioStreamPlayer.new()
	music_player.bus = "Music"
	music_player.volume_db = -10.0
	add_child(music_player)

	ambient_loop = AudioStreamPlayer.new()
	ambient_loop.bus = "SFX"
	ambient_loop.volume_db = -12.0
	add_child(ambient_loop)

	whale_player = AudioStreamPlayer.new()
	whale_player.bus = "SFX"
	whale_player.volume_db = -15.0
	add_child(whale_player)

	_whale_timer = Timer.new()
	_whale_timer.one_shot = true
	_whale_timer.timeout.connect(_on_whale_timer)
	add_child(_whale_timer)
	_schedule_next_whale()


func play_music(track_name: String) -> void:
	var path := MUSIC_PATH + track_name
	if not ResourceLoader.exists(path):
		return

	var stream: AudioStream = load(path)
	if stream == null:
		return

	music_player.stream = stream
	music_player.stream.loop = true
	music_player.volume_db = -40.0
	music_player.play()

	if _music_tween:
		_music_tween.kill()
	_music_tween = create_tween()
	_music_tween.tween_property(music_player, "volume_db", -10.0, 3.0).set_trans(Tween.TRANS_SINE)


func play_ambient_loop(loop_name: String) -> void:
	var path := SFX_PATH + loop_name
	if not ResourceLoader.exists(path):
		return

	var stream: AudioStream = load(path)
	if stream == null:
		return

	ambient_loop.stream = stream
	ambient_loop.stream.loop = true
	ambient_loop.play()


func play_whale_call_random() -> void:
	var path := SFX_PATH + "whale_call.ogg"
	if not ResourceLoader.exists(path):
		return
	if whale_player.playing:
		return

	var stream: AudioStream = load(path)
	if stream == null:
		return

	whale_player.stream = stream
	whale_player.play()


func play_bubble_sfx(position: Vector3) -> void:
	var path := SFX_PATH + "bubbles.ogg"
	if not ResourceLoader.exists(path):
		return

	var player := AudioStreamPlayer3D.new()
	player.bus = "SFX"
	player.volume_db = -8.0
	player.max_distance = 20.0
	player.attenuation_model = AudioStreamPlayer3D.ATTENUATION_INVERSE_SQUARE_DISTANCE
	add_child(player)
	player.global_position = position

	var stream: AudioStream = load(path)
	if stream == null:
		player.queue_free()
		return

	player.stream = stream
	player.play()
	player.finished.connect(player.queue_free)


func set_music_volume(db: float) -> void:
	music_player.volume_db = db


func set_sfx_volume(db: float) -> void:
	ambient_loop.volume_db = db
	whale_player.volume_db = db - 3.0


func _on_whale_timer() -> void:
	play_whale_call_random()
	_schedule_next_whale()


func _schedule_next_whale() -> void:
	_whale_timer.wait_time = randf_range(30.0, 90.0)
	_whale_timer.start()
