#pragma once

#include "CoreMinimal.h"
#include "UIActivatableScreen_Base.h"
#include "UILoginScreen_Base.generated.h"

class UUIButton_Base;
class UUICheckBox_Base;
class UUILabel_Base;
class UCommonTextBlock;
class UBorder;
class USaveGame;
class UZeusCharServerSubsystem;

/**
 * Tela de Login — reconstruída a partir do mock do Zeus UMG Forge
 * (WBP_LoginScreen) com os widgets compartilhados (UI_Button_Master,
 * UI_CheckBox_Master). Camada Abstract; o WBP concreto (WBP_Login) herda
 * DIRETO desta classe (ARQUITETURA.md §3.3).
 *
 * Auth: ao clicar "Entrar", envia C_CHAR_AUTH_REQUEST (opcode 2000) pelo
 * WebSocket do UZeusCharServerSubsystem como `uint8(PASSWORD) +
 * string(user) + string(password)`. CharServer chama AccountService.login
 * (Argon2id + lockout). S_CHAR_AUTH_OK → Flow::RequestEnterServerSelect;
 * reject (InvalidCredentials/AccountLocked/Suspended/etc.) → status
 * mapeado. Sem hard-ref de asset de tema (§5). Contas são criadas no
 * servidor via `npm run account`.
 */
UCLASS(Abstract, Blueprintable)
class ZMMO_API UUILoginScreen_Base : public UUIActivatableScreen_Base
{
	GENERATED_BODY()

protected:
	virtual void NativePreConstruct() override;
	virtual void NativeOnActivated() override;
	virtual void NativeOnDeactivated() override;
	virtual void RefreshUIStyle_Implementation() override;

	/** Textos de status/feedback da autenticação. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Login")
	FText IdleText = FText::FromString(TEXT("Acesso protegido pelo Farol da Manhã."));

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Login")
	FText AuthenticatingText = FText::FromString(TEXT("Autenticando…"));

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Login")
	FText NotConnectedText = FText::FromString(TEXT("Sem conexão com o Gateway."));

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Login")
	FText EmptyFieldsText = FText::FromString(TEXT("Informe usuário e senha."));

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Login")
	FText RejectedText = FText::FromString(TEXT("Acesso negado pelo Gateway."));

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Login")
	FText InvalidCredentialsText = FText::FromString(TEXT("Usuário ou senha inválidos."));

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Login")
	FText AccountLockedText = FText::FromString(TEXT("Conta bloqueada por excesso de tentativas. Aguarde e tente novamente."));

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Login")
	FText AccountSuspendedText = FText::FromString(TEXT("Conta suspensa. Contate o suporte."));

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Login")
	FText CredentialsDisabledText = FText::FromString(TEXT("Autenticação por credenciais indisponível no servidor."));

	// ---- Widgets do WBP (nomes esperados) ----
	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UBorder> Border_Bg;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UUILabel_Base> Input_User;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UUILabel_Base> Input_Password;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UUICheckBox_Base> RememberAccess;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UUIButton_Base> Btn_Login;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UUIButton_Base> Btn_Back;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UCommonTextBlock> Text_Status;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UCommonTextBlock> Text_Version;

private:
	UZeusCharServerSubsystem* GetCharServer() const;
	void SetBusy(bool bBusy);
	void SetStatus(const FText& InText);

	void HandleLoginClicked();
	void HandleBackClicked();

	UFUNCTION()
	void HandleCharRawMessage(int32 Opcode, const TArray<uint8>& Payload);

	/** "Lembrar Acesso" — async load do cache local (LoginCache slot) e
	    popula Input_User + Check_Remember se houver entrada salva. */
	void LoadRememberedAccess();

	UFUNCTION()
	void HandleLoadLoginCacheCompleted(const FString& InSlotName, int32 InUserIndex, USaveGame* LoadedGame);

	/** Salva (se checkbox marcada) ou apaga (se desmarcada) o cache de Login.
	    Chamado em HandleLoginClicked — antes do envio do auth, atende a
	    expectativa "marquei → vai lembrar próxima vez" independente do
	    resultado da autenticação. */
	void SaveOrClearRememberedAccess(const FString& User);

	bool bRawBound = false;
	bool bAwaitingAuth = false;
};
