// Copyright Pacificao. All Rights Reserved.

#include "AgrarianMvpFrontendWidget.h"

#include "Blueprint/WidgetTree.h"
#include "Components/Border.h"
#include "Components/Button.h"
#include "Components/ButtonSlot.h"
#include "Components/HorizontalBox.h"
#include "Components/HorizontalBoxSlot.h"
#include "Components/SizeBox.h"
#include "Components/TextBlock.h"
#include "Components/VerticalBox.h"
#include "Components/VerticalBoxSlot.h"
#include "GameFramework/PlayerController.h"
#include "InputCoreTypes.h"
#include "Styling/CoreStyle.h"
#include "TimerManager.h"

void UAgrarianMvpFrontendWidget::NativeConstruct()
{
	Super::NativeConstruct();
	SetIsFocusable(true);
	RebuildFrontendTree();
	FocusPrimaryButton();
}

FReply UAgrarianMvpFrontendWidget::NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent)
{
	if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection)
	{
		const FKey Key = InKeyEvent.GetKey();
		if (Key == EKeys::Left || Key == EKeys::A)
		{
			SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultMale);
			return FReply::Handled();
		}

		if (Key == EKeys::Right || Key == EKeys::D)
		{
			SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultFemale);
			return FReply::Handled();
		}

		if (Key == EKeys::Enter || Key == EKeys::SpaceBar)
		{
			ConfirmActiveScreen();
			return FReply::Handled();
		}
	}
	else if (ActiveScreen == EAgrarianMvpFrontendScreen::JoinServer)
	{
		const FKey Key = InKeyEvent.GetKey();
		if (Key == EKeys::Enter || Key == EKeys::SpaceBar)
		{
			ConfirmActiveScreen();
			return FReply::Handled();
		}

		if (Key == EKeys::BackSpace || Key == EKeys::Escape)
		{
			BackFromActiveScreen();
			return FReply::Handled();
		}
	}
	else if (ActiveScreen == EAgrarianMvpFrontendScreen::Loading)
	{
		const FKey Key = InKeyEvent.GetKey();
		if (Key == EKeys::Enter || Key == EKeys::SpaceBar)
		{
			ConfirmActiveScreen();
			return FReply::Handled();
		}
	}
	else if (ActiveScreen == EAgrarianMvpFrontendScreen::MainMenu)
	{
		const FKey Key = InKeyEvent.GetKey();
		if (Key == EKeys::Enter || Key == EKeys::SpaceBar || Key == EKeys::Escape)
		{
			ConfirmActiveScreen();
			return FReply::Handled();
		}

		if (Key == EKeys::Q)
		{
			SaveAndQuit();
			return FReply::Handled();
		}
	}
	else if (ActiveScreen == EAgrarianMvpFrontendScreen::SavingAndQuit)
	{
		return FReply::Handled();
	}

	return Super::NativeOnKeyDown(InGeometry, InKeyEvent);
}

void UAgrarianMvpFrontendWidget::SetActiveScreen(EAgrarianMvpFrontendScreen NewScreen)
{
	ActiveScreen = NewScreen;
	RebuildFrontendTree();
	FocusPrimaryButton();
}

void UAgrarianMvpFrontendWidget::SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype NewArchetype)
{
	SelectedCharacterArchetype = NewArchetype;
	RebuildFrontendTree();
	FocusPrimaryButton();
}

void UAgrarianMvpFrontendWidget::SetUiScale(float NewUiScale)
{
	UiScale = FMath::Clamp(NewUiScale, 0.75f, 1.5f);
	RebuildFrontendTree();
	FocusPrimaryButton();
}

void UAgrarianMvpFrontendWidget::SetHighContrastMode(bool bNewUseHighContrast)
{
	bUseHighContrast = bNewUseHighContrast;
	RebuildFrontendTree();
	FocusPrimaryButton();
}

void UAgrarianMvpFrontendWidget::ConfirmActiveScreen()
{
	ContinueFromActiveScreen();
}

void UAgrarianMvpFrontendWidget::BackFromActiveScreen()
{
	ReturnFromActiveScreen();
}

void UAgrarianMvpFrontendWidget::SaveAndQuit()
{
	SetActiveScreen(EAgrarianMvpFrontendScreen::SavingAndQuit);
	if (UWorld* World = GetWorld())
	{
		FTimerHandle SaveAndQuitTimerHandle;
		World->GetTimerManager().SetTimer(SaveAndQuitTimerHandle, this, &UAgrarianMvpFrontendWidget::ExecuteSaveAndQuit, 0.35f, false);
		return;
	}

	ExecuteSaveAndQuit();
}

void UAgrarianMvpFrontendWidget::ExecuteSaveAndQuit()
{
	if (APlayerController* PlayerController = GetOwningPlayer())
	{
		PlayerController->ConsoleCommand(TEXT("AgrarianSaveWorld"));
		PlayerController->ConsoleCommand(TEXT("quit"));
	}
}

void UAgrarianMvpFrontendWidget::ContinueFromActiveScreen()
{
	if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection)
	{
		CompleteFrontendFlow();
		return;
	}

	if (ActiveScreen == EAgrarianMvpFrontendScreen::JoinServer)
	{
		SetActiveScreen(EAgrarianMvpFrontendScreen::Loading);
		return;
	}

	if (ActiveScreen == EAgrarianMvpFrontendScreen::Loading)
	{
		CompleteFrontendFlow();
		return;
	}

	if (ActiveScreen == EAgrarianMvpFrontendScreen::SavingAndQuit)
	{
		return;
	}

	if (ActiveScreen == EAgrarianMvpFrontendScreen::MainMenu)
	{
		CompleteFrontendFlow();
		return;
	}
}

void UAgrarianMvpFrontendWidget::ReturnFromActiveScreen()
{
	if (ActiveScreen == EAgrarianMvpFrontendScreen::JoinServer)
	{
		SetActiveScreen(EAgrarianMvpFrontendScreen::CharacterSelection);
		return;
	}

	if (ActiveScreen == EAgrarianMvpFrontendScreen::MainMenu)
	{
		CompleteFrontendFlow();
	}
}

void UAgrarianMvpFrontendWidget::CompleteFrontendFlow()
{
	if (APlayerController* PlayerController = GetOwningPlayer())
	{
		if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection || ActiveScreen == EAgrarianMvpFrontendScreen::Loading)
		{
			PlayerController->ConsoleCommand(SelectedCharacterArchetype == EAgrarianMvpCharacterArchetype::YoungAdultFemale
				? TEXT("AgrarianSelectCharacter female")
				: TEXT("AgrarianSelectCharacter male"));
		}

		PlayerController->ConsoleCommand(TEXT("AgrarianCompleteFrontend"));
		PlayerController->SetInputMode(FInputModeGameOnly());
		PlayerController->bShowMouseCursor = false;
		PlayerController->SetIgnoreMoveInput(false);
		PlayerController->SetIgnoreLookInput(false);
	}

	RemoveFromParent();
}

void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
{
	if (!WidgetTree)
	{
		return;
	}

	PrimaryFocusButton = nullptr;

	const float Scale = FMath::Clamp(UiScale, 0.75f, 1.5f);
	const FLinearColor BackdropColor = bUseHighContrast ? FLinearColor::Black : FLinearColor(0.015f, 0.018f, 0.014f, 0.99f);
	const FLinearColor PanelColor = bUseHighContrast ? FLinearColor(0.0f, 0.0f, 0.0f, 0.98f) : FLinearColor(0.035f, 0.045f, 0.034f, 0.96f);
	const FLinearColor AccentColor = bUseHighContrast ? FLinearColor(0.95f, 0.95f, 0.30f, 1.0f) : FLinearColor(0.45f, 0.72f, 0.40f, 1.0f);
	const FLinearColor TextColor = bUseHighContrast ? FLinearColor::White : FLinearColor(0.92f, 0.98f, 0.84f, 1.0f);
	const FLinearColor MutedTextColor = bUseHighContrast ? FLinearColor(0.86f, 0.86f, 0.66f, 1.0f) : FLinearColor(0.72f, 0.80f, 0.68f, 1.0f);
	const FLinearColor ButtonColor = bUseHighContrast ? FLinearColor(0.30f, 0.30f, 0.02f, 1.0f) : FLinearColor(0.22f, 0.40f, 0.18f, 0.98f);
	const FLinearColor ButtonHoverColor = bUseHighContrast ? FLinearColor(0.48f, 0.48f, 0.08f, 1.0f) : FLinearColor(0.35f, 0.58f, 0.30f, 1.0f);
	const FLinearColor SecondaryButtonColor = bUseHighContrast ? FLinearColor(0.12f, 0.12f, 0.12f, 1.0f) : FLinearColor(0.10f, 0.13f, 0.09f, 0.98f);
	const FLinearColor QuitButtonColor = bUseHighContrast ? FLinearColor(0.32f, 0.10f, 0.08f, 1.0f) : FLinearColor(0.42f, 0.22f, 0.18f, 0.98f);

	UBorder* RootBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("MvpFrontendRoot"));
	RootBorder->SetBrushColor(BackdropColor);
	RootBorder->SetPadding(FMargin(24.0f * Scale));
	RootBorder->SetHorizontalAlignment(HAlign_Center);
	RootBorder->SetVerticalAlignment(VAlign_Center);
	WidgetTree->RootWidget = RootBorder;

	USizeBox* PanelSizeBox = WidgetTree->ConstructWidget<USizeBox>(USizeBox::StaticClass(), TEXT("MvpFrontendPanelSize"));
	PanelSizeBox->SetWidthOverride(780.0f * Scale);
	PanelSizeBox->SetMinDesiredWidth(420.0f);
	PanelSizeBox->SetMinDesiredHeight(300.0f);
	RootBorder->SetContent(PanelSizeBox);

	UBorder* PanelBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("MvpFrontendPanel"));
	PanelBorder->SetBrushColor(PanelColor);
	PanelBorder->SetPadding(FMargin(42.0f * Scale, 34.0f * Scale));
	PanelSizeBox->SetContent(PanelBorder);

	UVerticalBox* Panel = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("MvpFrontendStack"));
	PanelBorder->SetContent(Panel);

	if (ActiveScreen == EAgrarianMvpFrontendScreen::MainMenu)
	{
		AddText(Panel, FText::FromString(TEXT("Pause Menu")), FMath::RoundToInt(20.0f * Scale), true, AccentColor, 6.0f * Scale);
		AddText(Panel, MainMenuTitle, FMath::RoundToInt(54.0f * Scale), true, TextColor, 6.0f * Scale);
		AddText(Panel, FText::FromString(TEXT("Gameplay is paused while this menu is active.")), FMath::RoundToInt(22.0f * Scale), false, MutedTextColor, 72.0f * Scale);
		PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Resume")), ButtonColor, ButtonHoverColor, 16.0f * Scale);
		PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked);

		UButton* QuitButton = AddButton(Panel, FText::FromString(TEXT("Save & Quit")), QuitButtonColor, FLinearColor(0.58f, 0.28f, 0.22f, 1.0f), 34.0f * Scale);
		QuitButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleSaveAndQuitClicked);
		AddText(Panel, FText::FromString(TEXT("Escape opens this menu. Save & Quit writes the current world save before closing.")), FMath::RoundToInt(16.0f * Scale), false, MutedTextColor, 0.0f);
		return;
	}

	if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection)
	{
		AddText(Panel, FText::FromString(TEXT("Character Selection")), FMath::RoundToInt(18.0f * Scale), true, AccentColor, 6.0f * Scale);
		AddText(Panel, FText::FromString(TEXT("Choose your first pioneer")), FMath::RoundToInt(34.0f * Scale), true, TextColor, 6.0f * Scale);
		AddText(Panel, FText::FromString(TEXT("Select the person who will step into Ground Zero.")), FMath::RoundToInt(18.0f * Scale), false, MutedTextColor, 24.0f * Scale);

		UHorizontalBox* CharacterRow = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("CharacterRow"));
		if (UVerticalBoxSlot* RowSlot = Panel->AddChildToVerticalBox(CharacterRow))
		{
			RowSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, 22.0f * Scale));
		}

		const bool bMaleSelected = SelectedCharacterArchetype == EAgrarianMvpCharacterArchetype::YoungAdultMale;
		const bool bFemaleSelected = SelectedCharacterArchetype == EAgrarianMvpCharacterArchetype::YoungAdultFemale;
		UButton* MaleButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("MalePioneerButton"));
		MaleButton->SetBackgroundColor(bMaleSelected ? ButtonHoverColor : SecondaryButtonColor);
		MaleButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleMaleCharacterClicked);
		UVerticalBox* MaleStack = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("MalePioneerStack"));
		MaleButton->SetContent(MaleStack);
		AddText(MaleStack, FText::FromString(TEXT("Young adult male")), FMath::RoundToInt(21.0f * Scale), true, TextColor, 8.0f * Scale);
		AddText(MaleStack, FText::FromString(TEXT("Average build, practical workwear proxy, survival baseline.")), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 18.0f * Scale);
		AddText(MaleStack, bMaleSelected ? FText::FromString(TEXT("Selected")) : FText::FromString(TEXT("Available")), FMath::RoundToInt(15.0f * Scale), true, bMaleSelected ? AccentColor : MutedTextColor, 0.0f);
		if (UHorizontalBoxSlot* MaleSlot = CharacterRow->AddChildToHorizontalBox(MaleButton))
		{
			MaleSlot->SetPadding(FMargin(0.0f, 0.0f, 12.0f * Scale, 0.0f));
			MaleSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
		}

		UButton* FemaleButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("FemalePioneerButton"));
		FemaleButton->SetBackgroundColor(bFemaleSelected ? ButtonHoverColor : SecondaryButtonColor);
		FemaleButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleFemaleCharacterClicked);
		UVerticalBox* FemaleStack = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("FemalePioneerStack"));
		FemaleButton->SetContent(FemaleStack);
		AddText(FemaleStack, FText::FromString(TEXT("Young adult female")), FMath::RoundToInt(21.0f * Scale), true, TextColor, 8.0f * Scale);
		AddText(FemaleStack, FText::FromString(TEXT("Average build, practical workwear proxy, survival baseline.")), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 18.0f * Scale);
		AddText(FemaleStack, bFemaleSelected ? FText::FromString(TEXT("Selected")) : FText::FromString(TEXT("Available")), FMath::RoundToInt(15.0f * Scale), true, bFemaleSelected ? AccentColor : MutedTextColor, 0.0f);
		if (UHorizontalBoxSlot* FemaleSlot = CharacterRow->AddChildToHorizontalBox(FemaleButton))
		{
			FemaleSlot->SetPadding(FMargin(12.0f * Scale, 0.0f, 0.0f, 0.0f));
			FemaleSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
		}

		PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Enter Ground Zero")), ButtonColor, ButtonHoverColor, 10.0f * Scale);
		PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked);
		AddText(Panel, FText::Format(FText::FromString(TEXT("Selected {0}: {1}. Click a card or use Left/Right, then continue.")), GetSelectedRoleLabel(), GetSelectedCharacterLabel()), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 0.0f);
		return;
	}

	if (ActiveScreen == EAgrarianMvpFrontendScreen::JoinServer)
	{
		AddText(Panel, FText::FromString(TEXT("Server Join")), FMath::RoundToInt(18.0f * Scale), true, AccentColor, 6.0f * Scale);
		AddText(Panel, FText::FromString(TEXT("Join MVP server")), FMath::RoundToInt(34.0f * Scale), true, TextColor, 8.0f * Scale);
		AddText(Panel, FText::Format(FText::FromString(TEXT("{0}: {1}")), GetSelectedRoleLabel(), GetSelectedCharacterLabel()), FMath::RoundToInt(18.0f * Scale), false, MutedTextColor, 36.0f * Scale);
		AddText(Panel, FText::FromString(TEXT("Server address")), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 4.0f * Scale);
		AddText(Panel, JoinServerAddress, FMath::RoundToInt(24.0f * Scale), true, TextColor, 42.0f * Scale);

		UHorizontalBox* ButtonRow = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("JoinButtonRow"));
		if (UVerticalBoxSlot* RowSlot = Panel->AddChildToVerticalBox(ButtonRow))
		{
			RowSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, 18.0f * Scale));
		}

		PrimaryFocusButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("ContinueToLoadingButton"));
		PrimaryFocusButton->SetBackgroundColor(ButtonColor);
		PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked);
		UTextBlock* ContinueLabel = AddText(nullptr, FText::FromString(TEXT("Continue to loading")), FMath::RoundToInt(20.0f * Scale), true, TextColor, 0.0f);
		PrimaryFocusButton->SetContent(ContinueLabel);
		if (UButtonSlot* ContinueLabelSlot = Cast<UButtonSlot>(ContinueLabel->Slot))
		{
			ContinueLabelSlot->SetPadding(FMargin(22.0f, 12.0f));
			ContinueLabelSlot->SetHorizontalAlignment(HAlign_Center);
		}
		if (UHorizontalBoxSlot* ContinueSlot = ButtonRow->AddChildToHorizontalBox(PrimaryFocusButton))
		{
			ContinueSlot->SetPadding(FMargin(0.0f, 0.0f, 12.0f * Scale, 0.0f));
			ContinueSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
		}

		UButton* BackButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("BackButton"));
		BackButton->SetBackgroundColor(SecondaryButtonColor);
		BackButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleBackClicked);
		UTextBlock* BackLabel = AddText(nullptr, FText::FromString(TEXT("Back")), FMath::RoundToInt(20.0f * Scale), true, TextColor, 0.0f);
		BackButton->SetContent(BackLabel);
		if (UButtonSlot* BackLabelSlot = Cast<UButtonSlot>(BackLabel->Slot))
		{
			BackLabelSlot->SetPadding(FMargin(22.0f, 12.0f));
			BackLabelSlot->SetHorizontalAlignment(HAlign_Center);
		}
		if (UHorizontalBoxSlot* BackSlot = ButtonRow->AddChildToHorizontalBox(BackButton))
		{
			BackSlot->SetPadding(FMargin(12.0f * Scale, 0.0f, 0.0f, 0.0f));
			BackSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
		}

		AddText(Panel, FText::FromString(TEXT("Click continue, press Enter, or press Backspace/Escape to revise your pioneer.")), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 0.0f);
		return;
	}

	if (ActiveScreen == EAgrarianMvpFrontendScreen::SavingAndQuit)
	{
		AddText(Panel, FText::FromString(TEXT("Saving World")), FMath::RoundToInt(20.0f * Scale), true, AccentColor, 6.0f * Scale);
		AddText(Panel, FText::FromString(TEXT("Writing the current world state")), FMath::RoundToInt(34.0f * Scale), true, TextColor, 8.0f * Scale);
		AddText(Panel, FText::FromString(TEXT("The demo will close after the save command is issued.")), FMath::RoundToInt(18.0f * Scale), false, MutedTextColor, 0.0f);
		return;
	}

	AddText(Panel, FText::FromString(TEXT("Loading Segment")), FMath::RoundToInt(18.0f * Scale), true, AccentColor, 6.0f * Scale);
	AddText(Panel, FText::FromString(TEXT("Preparing Ground Zero")), FMath::RoundToInt(34.0f * Scale), true, TextColor, 8.0f * Scale);
	AddText(Panel, FText::FromString(TEXT("Loading terrain, weather, survival state, and server session data.")), FMath::RoundToInt(18.0f * Scale), false, MutedTextColor, 70.0f * Scale);
	AddText(Panel, FText::Format(FText::FromString(TEXT("{0}: {1} | Server: {2}")), GetSelectedRoleLabel(), GetSelectedCharacterLabel(), JoinServerAddress), FMath::RoundToInt(18.0f * Scale), false, TextColor, 34.0f * Scale);
	PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Enter Ground Zero")), ButtonColor, ButtonHoverColor, 14.0f * Scale);
	PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked);
	AddText(Panel, FText::FromString(TEXT("Click or press Enter to close the MVP menu and begin testing.")), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 0.0f);
}

UTextBlock* UAgrarianMvpFrontendWidget::AddText(UVerticalBox* Parent, const FText& Text, int32 FontSize, bool bBold, const FLinearColor& Color, float BottomPadding)
{
	UTextBlock* TextBlock = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass());
	TextBlock->SetText(Text);
	TextBlock->SetFont(FCoreStyle::GetDefaultFontStyle(bBold ? "Bold" : "Regular", FontSize));
	TextBlock->SetColorAndOpacity(FSlateColor(Color));
	TextBlock->SetAutoWrapText(true);
	TextBlock->SetJustification(ETextJustify::Left);

	if (Parent)
	{
		if (UVerticalBoxSlot* TextSlot = Parent->AddChildToVerticalBox(TextBlock))
		{
			TextSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, BottomPadding));
		}
	}

	return TextBlock;
}

UButton* UAgrarianMvpFrontendWidget::AddButton(UVerticalBox* Parent, const FText& Text, const FLinearColor& NormalColor, const FLinearColor& HoveredColor, float BottomPadding)
{
	UButton* Button = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass());
	Button->SetBackgroundColor(NormalColor);
	Button->SetClickMethod(EButtonClickMethod::MouseDown);
	Button->SetTouchMethod(EButtonTouchMethod::Down);

	if (!Text.IsEmpty())
	{
		UTextBlock* Label = AddText(nullptr, Text, FMath::RoundToInt(20.0f * FMath::Clamp(UiScale, 0.75f, 1.5f)), true, FLinearColor(0.96f, 1.0f, 0.90f, 1.0f), 0.0f);
		Button->SetContent(Label);
		if (UButtonSlot* LabelSlot = Cast<UButtonSlot>(Label->Slot))
		{
			LabelSlot->SetPadding(FMargin(22.0f, 12.0f));
			LabelSlot->SetHorizontalAlignment(HAlign_Center);
		}
	}

	if (Parent)
	{
		if (UVerticalBoxSlot* ButtonSlot = Parent->AddChildToVerticalBox(Button))
		{
			ButtonSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, BottomPadding));
			ButtonSlot->SetHorizontalAlignment(HAlign_Left);
		}
	}

	return Button;
}

void UAgrarianMvpFrontendWidget::FocusPrimaryButton()
{
	if (PrimaryFocusButton)
	{
		PrimaryFocusButton->SetKeyboardFocus();
	}
	else
	{
		SetKeyboardFocus();
	}
}

void UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked()
{
	DeferFrontendAction([this]()
	{
		ConfirmActiveScreen();
	});
}

void UAgrarianMvpFrontendWidget::HandleBackClicked()
{
	DeferFrontendAction([this]()
	{
		BackFromActiveScreen();
	});
}

void UAgrarianMvpFrontendWidget::HandleSaveAndQuitClicked()
{
	DeferFrontendAction([this]()
	{
		SaveAndQuit();
	});
}

void UAgrarianMvpFrontendWidget::HandleMaleCharacterClicked()
{
	DeferFrontendAction([this]()
	{
		SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultMale);
	});
}

void UAgrarianMvpFrontendWidget::HandleFemaleCharacterClicked()
{
	DeferFrontendAction([this]()
	{
		SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultFemale);
	});
}

void UAgrarianMvpFrontendWidget::DeferFrontendAction(TFunction<void()> Action)
{
	if (!Action)
	{
		return;
	}

	if (UWorld* World = GetWorld())
	{
		FTimerDelegate DeferredAction;
		DeferredAction.BindLambda([WeakThis = TWeakObjectPtr<UAgrarianMvpFrontendWidget>(this), Action = MoveTemp(Action)]() mutable
		{
			if (WeakThis.IsValid())
			{
				Action();
			}
		});
		World->GetTimerManager().SetTimerForNextTick(DeferredAction);
		return;
	}

	Action();
}

FText UAgrarianMvpFrontendWidget::GetSelectedCharacterLabel() const
{
	return SelectedCharacterArchetype == EAgrarianMvpCharacterArchetype::YoungAdultFemale
		? FText::FromString(TEXT("young adult female"))
		: FText::FromString(TEXT("young adult male"));
}

FText UAgrarianMvpFrontendWidget::GetSelectedRoleLabel() const
{
	return FText::FromString(TEXT("Pioneer"));
}
