#pragma once

#include "lite_connection_service.h"
#include "lite_wallet_server_lifecycle_readiness.h"
#include "wallet_capabilities.h"

#include "../config/settings.h"

#include <cstddef>
#include <string>
#include <vector>

namespace dragonx {
namespace wallet {

enum class LiteWalletServerSelectionUiExecutionStatus {
    ReadyForFutureLifecycle,
    WaitingForLiteBuild,
    WaitingForBackendCapability,
    WaitingForSettings,
    WaitingForServerSelection,
    WaitingForPersistenceOwner,
    WaitingForDisplayStatus,
    WaitingForLifecycleUi,
    WaitingForPrivateDataRedaction,
    WaitingForSyncPlannerFeed,
    SettingsSaveFailed,
    RuntimeExecutionDisabled
};

enum class LiteWalletServerSelectionUiExecutionIssue {
    FullNodeBuild,
    LiteBackendCapabilityMissing,
    SettingsNotLoaded,
    ServerSelectionMissing,
    ServerPersistenceOwnerMissing,
    SelectedServerDisplayMissing,
    LifecycleUiOwnerMissing,
    PrivateDataRedactionMissing,
    SyncPlannerFeedMissing,
    SettingsSaveFailed,
    ServerConnectivityCheckRequested,
    WalletLifecycleExecutionRequested,
    SyncRequested,
    SyncStatusPollingRequested,
    WorkerQueueRequested,
    WalletStateMutationRequested,
    WalletFilePersistenceRequested,
    SendImportExportRequested
};

struct LiteWalletServerSelectionUiIntent {
    bool selectedServerIntentProvided = false;
    LiteServerSelectionMode selectionMode = LiteServerSelectionMode::Sticky;
    std::string selectedServerUrl;
    std::size_t randomSelectionSeed = 0;
    std::string chainName;
    bool replaceServers = false;
    std::vector<LiteServerEndpoint> servers;
};

struct LiteWalletServerSelectionPersistenceExecutionInput {
    bool settingsLoaded = true;
    bool havePersistedSelectionIntent = true;
    bool persistSelectedServer = true;
    bool persistenceOwnerReady = true;
    bool writeSettings = false;
    std::string settingsSavePath;
};

struct LiteWalletServerSelectionUiExecutionInput {
    WalletCapabilities capabilities;
    LiteWalletServerSelectionUiIntent intent;
    LiteWalletServerSelectionPersistenceExecutionInput persistence;
    LiteWalletLifecycleUiPrerequisites ui;
    LiteWalletLifecycleOperation operation = LiteWalletLifecycleOperation::CreateNew;
    LiteWalletCreateRequest createRequest;
    LiteWalletOpenRequest openRequest;
    LiteWalletRestoreRequest restoreRequest;
    bool requireLifecycleReadiness = false;

    bool serverConnectivityCheckRequested = false;
    bool walletExistsCheckRequested = false;
    bool walletLifecycleExecutionRequested = false;
    bool syncStartRequested = false;
    bool syncStatusPollingRequested = false;
    bool workerQueueEnqueueRequested = false;
    bool walletStateMutationRequested = false;
    bool walletFilePersistenceRequested = false;
    bool sendImportExportExecutionRequested = false;
};

struct LiteWalletServerSelectionUiExecutionIssueInfo {
    LiteWalletServerSelectionUiExecutionIssue issue = LiteWalletServerSelectionUiExecutionIssue::SettingsNotLoaded;
    std::string message;
};

struct LiteWalletServerSelectionUiExecutionResult {
    bool ok = false;
    bool dryRunOnly = true;
    bool noNetwork = true;
    bool noBridgeCalls = true;
    bool noServerHealthChecked = true;
    bool noWalletExistsChecked = true;
    bool noWalletCreated = true;
    bool noWalletOpened = true;
    bool noWalletRestored = true;
    bool noSyncStarted = true;
    bool noSyncStatusPolled = true;
    bool noWalletPersistence = true;
    bool noSendImportExportExecution = true;
    bool workerQueueEnqueued = false;
    bool stateMutationAllowed = false;
    bool stateMutated = false;
    bool walletStateWritten = false;
    bool settingsMutationAllowed = true;
    bool settingsMutated = false;
    bool noSettingsPersistence = true;
    bool settingsWritten = false;
    bool settingsPersistenceAccepted = false;
    bool selectedServerIntentAccepted = false;
    bool lifecycleReadinessAccepted = false;
    bool lifecycleReportCouldFeedSyncPlanners = false;
    bool selectedServerRedacted = false;
    LiteWalletServerSelectionUiExecutionStatus status = LiteWalletServerSelectionUiExecutionStatus::WaitingForSettings;
    std::string error;
    std::string selectedServerUrlRedacted;
    std::string diagnosticSummary;
    LiteConnectionSettings connectionSettings;
    LiteServerSelectionResult selectedServer;
    LiteWalletServerLifecycleReadinessInput lifecycleInput;
    LiteWalletServerLifecycleReadinessResult lifecycleReadiness;
    std::vector<LiteWalletServerSelectionUiExecutionIssueInfo> issues;
};

LiteConnectionSettings liteConnectionSettingsFromAppSettings(const config::Settings& settings);
void applyLiteConnectionSettingsToAppSettings(config::Settings& settings,
                                              const LiteConnectionSettings& connectionSettings);
const char* liteWalletServerSelectionUiExecutionStatusName(
    LiteWalletServerSelectionUiExecutionStatus status);
const char* liteWalletServerSelectionUiExecutionIssueName(
    LiteWalletServerSelectionUiExecutionIssue issue);
std::string redactLiteServerSelectionValue(const std::string& value);

LiteWalletServerSelectionUiExecutionResult executeLiteWalletServerSelectionUi(
    config::Settings& settings,
    const LiteWalletServerSelectionUiExecutionInput& input);

} // namespace wallet
} // namespace dragonx