#pragma once

#include "lite_wallet_lifecycle_service.h"
#include "lite_wallet_sync_app_refresh_integration.h"

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

namespace dragonx::wallet {

enum class LiteWalletServerLifecycleReadinessStatus {
    ReadyForFutureLifecycle,
    WaitingForLiteBuild,
    WaitingForBackendCapability,
    WaitingForServerSelection,
    WaitingForPersistenceIntent,
    WaitingForDisplayStatus,
    WaitingForLifecycleUi,
    WaitingForPrivateDataRedaction,
    WaitingForSyncPlannerFeed,
    RuntimeExecutionDisabled,
};

enum class LiteWalletServerLifecycleReadinessIssue {
    FullNodeBuild,
    LiteBackendCapabilityMissing,
    PersistedSettingsNotLoaded,
    PersistedServerSelectionIntentMissing,
    ServerSelectionMissing,
    ServerPersistenceOwnerMissing,
    SelectedServerDisplayMissing,
    LifecycleUiOwnerMissing,
    LifecycleOperationUnconfirmed,
    OpenWalletPathMissing,
    RestoreSeedMissing,
    PrivateDataRedactionMissing,
    SyncPlannerFeedMissing,
    RealLifecycleExecutionRequested,
};

enum class LiteWalletSelectedServerDisplayStatus {
    Hidden,
    SelectedServer,
    CustomServer,
    Missing,
};

struct LiteWalletServerSelectionPersistenceInput {
    bool settingsLoaded = false;
    bool havePersistedSelectionIntent = false;
    bool persistSelectedServer = false;
    bool persistenceOwnerReady = false;
};

struct LiteWalletLifecycleUiPrerequisites {
    bool selectedServerDisplayReady = false;
    bool lifecycleUiOwnerReady = false;
    bool operationConfirmed = false;
    bool privateDataRedactionReady = false;
    bool syncPlannerFeedReady = false;
    bool realLifecycleExecutionRequested = false;
};

struct LiteWalletServerLifecycleReadinessInput {
    WalletCapabilities capabilities;
    LiteConnectionSettings settings;
    LiteWalletLifecycleOperation operation = LiteWalletLifecycleOperation::CreateNew;
    LiteWalletServerSelectionPersistenceInput persistence;
    LiteWalletLifecycleUiPrerequisites ui;
    LiteWalletCreateRequest createRequest;
    LiteWalletOpenRequest openRequest;
    LiteWalletRestoreRequest restoreRequest;
};

struct LiteWalletServerLifecycleReadinessOptions {
    bool requireLiteBuild = true;
    bool requireLiteBackendCapability = true;
    bool requirePersistedSettingsLoaded = true;
    bool requirePersistedSelectionIntent = true;
    bool requireSelectedServerDisplay = true;
    bool requireLifecycleUiOwner = true;
    bool requireOperationConfirmation = true;
    bool requirePrivateDataRedaction = true;
    bool requireSyncPlannerFeed = true;
};

struct LiteWalletSelectedServerDisplayReport {
    bool ok = false;
    LiteWalletSelectedServerDisplayStatus status = LiteWalletSelectedServerDisplayStatus::Hidden;
    std::string label;
    std::string url;
    std::size_t serverIndex = 0;
    bool customServer = false;
    std::string message;
};

struct LiteWalletServerSelectionPersistencePlan {
    bool ok = false;
    bool settingsLoaded = false;
    bool persistedSelectionIntentAccepted = false;
    bool wouldPersistSelectedServer = false;
    bool persistenceOwnerAccepted = false;
    bool settingsWritten = false;
    LiteServerSelectionMode selectionMode = LiteServerSelectionMode::Sticky;
    std::string selectedServerUrl;
    std::size_t selectedServerIndex = 0;
    bool selectedServerCustom = false;
    std::string error;
};

struct LiteWalletLifecycleUiRequestPlan {
    bool ok = false;
    LiteWalletLifecycleOperation operation = LiteWalletLifecycleOperation::CreateNew;
    LiteWalletLifecyclePlan lifecyclePlan;
    std::vector<LiteRedactedPrivateData> privateData;
    bool privateInputsRedacted = true;
    std::string requestSummary;
    std::string error;
};

struct LiteWalletServerLifecycleReadinessIssueInfo {
    LiteWalletServerLifecycleReadinessIssue issue = LiteWalletServerLifecycleReadinessIssue::FullNodeBuild;
    std::string message;
};

struct LiteWalletServerLifecycleReadinessResult {
    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 noSettingsPersistence = true;
    bool settingsWritten = false;
    bool workerQueueEnqueued = false;
    bool stateMutationAllowed = false;
    bool stateMutated = false;
    bool walletStateWritten = false;
    bool walletReady = false;

    bool liteBuildAccepted = false;
    bool backendCapabilityAccepted = false;
    bool serverSelectionAccepted = false;
    bool persistenceIntentAccepted = false;
    bool selectedServerDisplayAccepted = false;
    bool lifecycleUiOwnerAccepted = false;
    bool requestAccepted = false;
    bool privateDataRedactionAccepted = false;
    bool syncPlannerFeedAccepted = false;
    bool futureLifecycleCouldBeEnabled = false;
    bool lifecycleReportCouldFeedSyncPlanners = false;

    LiteWalletServerLifecycleReadinessStatus status = LiteWalletServerLifecycleReadinessStatus::WaitingForLiteBuild;
    WalletCapabilities capabilities;
    LiteServerSelectionResult selectedServer;
    LiteWalletSelectedServerDisplayReport selectedServerDisplay;
    LiteWalletServerSelectionPersistencePlan persistencePlan;
    LiteWalletLifecycleUiRequestPlan requestPlan;
    LiteWalletSyncAppRefreshLifecycleInput syncLifecycleInput;
    WalletBackendStatus lifecycleStatus;
    std::vector<LiteWalletServerLifecycleReadinessIssueInfo> issues;
    std::string error;
};

const char* liteWalletServerLifecycleReadinessStatusName(
    LiteWalletServerLifecycleReadinessStatus status);
const char* liteWalletServerLifecycleReadinessIssueName(
    LiteWalletServerLifecycleReadinessIssue issue);
const char* liteWalletSelectedServerDisplayStatusName(
    LiteWalletSelectedServerDisplayStatus status);

LiteWalletServerLifecycleReadinessResult evaluateLiteWalletServerLifecycleReadiness(
    const LiteWalletServerLifecycleReadinessInput& input,
    LiteWalletServerLifecycleReadinessOptions options = {});
LiteWalletSyncAppRefreshLifecycleInput liteWalletSyncLifecycleInputFromServerLifecycleReadiness(
    const LiteWalletServerLifecycleReadinessResult& result);

class LiteWalletServerLifecycleReadinessPlanner {
public:
    explicit LiteWalletServerLifecycleReadinessPlanner(
        LiteWalletServerLifecycleReadinessOptions options = {});

    LiteWalletServerLifecycleReadinessResult evaluate(
        const LiteWalletServerLifecycleReadinessInput& input) const;

private:
    LiteWalletServerLifecycleReadinessOptions options_;
};

} // namespace dragonx::wallet