// © 2025 Naked People Team. All Rights Reserved.


#include "AudioSettingsSubsystem.h"

#include "AudioSettingsConfig.h"
#include "NakedDesireGameInstance.h"
#include "NakedDesireUserSettings.h"
#include "Kismet/GameplayStatics.h"
#include "Sound/SoundClass.h"
#include "Sound/SoundMix.h"
#include "UObject/UObjectGlobals.h"

void UAudioSettingsSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
	Super::Initialize(Collection);

	if (UNakedDesireUserSettings* Settings = UNakedDesireUserSettings::GetNakedDesireUserSettings())
		Settings->OnSettingsChanged.AddUniqueDynamic(this, &UAudioSettingsSubsystem::HandleSettingsChanged);

	// SoundMix overrides are world-scoped, so re-push them every time a level finishes loading.
	MapLoadHandle = FCoreUObjectDelegates::PostLoadMapWithWorld.AddUObject(this, &UAudioSettingsSubsystem::HandleMapLoaded);
}

void UAudioSettingsSubsystem::Deinitialize()
{
	if (UNakedDesireUserSettings* Settings = UNakedDesireUserSettings::GetNakedDesireUserSettings())
		Settings->OnSettingsChanged.RemoveDynamic(this, &UAudioSettingsSubsystem::HandleSettingsChanged);

	FCoreUObjectDelegates::PostLoadMapWithWorld.Remove(MapLoadHandle);

	Super::Deinitialize();
}

void UAudioSettingsSubsystem::HandleSettingsChanged(UNakedDesireUserSettings* Settings)
{
	ApplyVolumes();
}

void UAudioSettingsSubsystem::HandleMapLoaded(UWorld* LoadedWorld)
{
	ApplyVolumes();
}

void UAudioSettingsSubsystem::ApplyVolumes()
{
	const UNakedDesireGameInstance* GameInstance = Cast<UNakedDesireGameInstance>(GetGameInstance());
	if (!GameInstance || !GameInstance->AudioConfig)
		return;

	const UAudioSettingsConfig* Config = GameInstance->AudioConfig;
	if (!Config->SettingsMix)
		return;

	UWorld* World = GetWorld();
	if (!World)
		return;

	const UNakedDesireUserSettings* Settings = UNakedDesireUserSettings::GetNakedDesireUserSettings();
	if (!Settings)
		return;

	auto ApplyClass = [&](USoundClass* SoundClass, float Volume)
	{
		if (!SoundClass)
			return;
		// Pitch 1.0, no fade — instantaneous so the slider feels responsive.
		UGameplayStatics::SetSoundMixClassOverride(World, Config->SettingsMix, SoundClass, Volume, 1.0f, 0.0f, true);
	};

	ApplyClass(Config->MasterClass, Settings->GetGlobalVolume());
	ApplyClass(Config->MusicClass, Settings->GetMusicVolume());
	ApplyClass(Config->SfxClass, Settings->GetSfxVolume());

	UGameplayStatics::PushSoundMixModifier(World, Config->SettingsMix);
}