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


#include "GraphicsSettingsTab.h"

#include "Components/CheckBox.h"
#include "Components/ComboBoxString.h"
#include "Kismet/KismetSystemLibrary.h"
#include "NakedDesire/Global/NakedDesireUserSettings.h"

namespace
{
	// Combo order → EWindowMode. Index-aligned with the WindowModeCombo entries below.
	constexpr EWindowMode::Type WindowModes[] = {
		EWindowMode::Fullscreen,
		EWindowMode::WindowedFullscreen,
		EWindowMode::Windowed
	};

	FString ResolutionToText(const FIntPoint& Resolution)
	{
		return FString::Printf(TEXT("%d x %d"), Resolution.X, Resolution.Y);
	}
}

void UGraphicsSettingsTab::NativeConstruct()
{
	Super::NativeConstruct();

	QualityCombo->OnSelectionChanged.AddUniqueDynamic(this, &UGraphicsSettingsTab::OnQualityChanged);
	WindowModeCombo->OnSelectionChanged.AddUniqueDynamic(this, &UGraphicsSettingsTab::OnWindowModeChanged);
	ResolutionCombo->OnSelectionChanged.AddUniqueDynamic(this, &UGraphicsSettingsTab::OnResolutionChanged);
	VSyncCheckBox->OnCheckStateChanged.AddUniqueDynamic(this, &UGraphicsSettingsTab::OnVSyncChanged);

	RefreshFromSettings();
}

void UGraphicsSettingsTab::RefreshFromSettings()
{
	const UNakedDesireUserSettings* Settings = UNakedDesireUserSettings::GetNakedDesireUserSettings();
	if (!Settings)
		return;

	// Quality presets (Scalability levels 0-3).
	QualityCombo->ClearOptions();
	QualityCombo->AddOption(TEXT("Low"));
	QualityCombo->AddOption(TEXT("Medium"));
	QualityCombo->AddOption(TEXT("High"));
	QualityCombo->AddOption(TEXT("Epic"));
	const int32 Quality = FMath::Clamp(Settings->GetOverallScalabilityLevel(), 0, 3);
	QualityCombo->SetSelectedIndex(Quality);

	// Window mode.
	WindowModeCombo->ClearOptions();
	WindowModeCombo->AddOption(TEXT("Fullscreen"));
	WindowModeCombo->AddOption(TEXT("Borderless Windowed"));
	WindowModeCombo->AddOption(TEXT("Windowed"));
	const EWindowMode::Type CurrentMode = Settings->GetFullscreenMode();
	int32 ModeIndex = 0;
	for (int32 i = 0; i < UE_ARRAY_COUNT(WindowModes); ++i)
	{
		if (WindowModes[i] == CurrentMode)
		{
			ModeIndex = i;
			break;
		}
	}
	WindowModeCombo->SetSelectedIndex(ModeIndex);

	// Resolutions.
	ResolutionCombo->ClearOptions();
	AvailableResolutions.Reset();
	UKismetSystemLibrary::GetSupportedFullscreenResolutions(AvailableResolutions);
	const FIntPoint CurrentResolution = Settings->GetScreenResolution();
	int32 ResolutionIndex = INDEX_NONE;
	for (int32 i = 0; i < AvailableResolutions.Num(); ++i)
	{
		ResolutionCombo->AddOption(ResolutionToText(AvailableResolutions[i]));
		if (AvailableResolutions[i] == CurrentResolution)
			ResolutionIndex = i;
	}
	// Current resolution may not be in the supported list (e.g. windowed) — surface it anyway.
	if (ResolutionIndex == INDEX_NONE)
	{
		ResolutionCombo->AddOption(ResolutionToText(CurrentResolution));
		AvailableResolutions.Add(CurrentResolution);
		ResolutionIndex = AvailableResolutions.Num() - 1;
	}
	ResolutionCombo->SetSelectedIndex(ResolutionIndex);

	VSyncCheckBox->SetIsChecked(Settings->IsVSyncEnabled());
}

void UGraphicsSettingsTab::OnQualityChanged(FString SelectedItem, ESelectInfo::Type SelectionType)
{
	if (SelectionType == ESelectInfo::Direct)
		return;

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

	Settings->SetOverallScalabilityLevel(QualityCombo->GetSelectedIndex());
}

void UGraphicsSettingsTab::OnWindowModeChanged(FString SelectedItem, ESelectInfo::Type SelectionType)
{
	if (SelectionType == ESelectInfo::Direct)
		return;

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

	const int32 Index = FMath::Clamp(WindowModeCombo->GetSelectedIndex(), 0, static_cast<int32>(UE_ARRAY_COUNT(WindowModes)) - 1);
	Settings->SetFullscreenMode(WindowModes[Index]);
}

void UGraphicsSettingsTab::OnResolutionChanged(FString SelectedItem, ESelectInfo::Type SelectionType)
{
	if (SelectionType == ESelectInfo::Direct)
		return;

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

	const int32 Index = ResolutionCombo->GetSelectedIndex();
	if (AvailableResolutions.IsValidIndex(Index))
		Settings->SetScreenResolution(AvailableResolutions[Index]);
}

void UGraphicsSettingsTab::OnVSyncChanged(bool bIsChecked)
{
	if (UNakedDesireUserSettings* Settings = UNakedDesireUserSettings::GetNakedDesireUserSettings())
		Settings->SetVSyncEnabled(bIsChecked);
}