#pragma once

#include "lite_wallet_sync_app_refresh_integration.h"
#include "wallet_capabilities.h"

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

namespace dragonx::wallet {

enum class LiteWalletSyncExecutionReadinessStatus {
    ReadyToEnableSyncExecution,
    WaitingForLiteBuild,
    WaitingForArtifact,
    WaitingForBackendLink,
    WaitingForBridge,
    WaitingForIntegration,
    WaitingForExecutionOwner,
    WaitingForCancellation,
    WaitingForShutdown,
    WaitingForRetry,
    WaitingForRecovery,
    UnsafePlan,
};

enum class LiteWalletSyncExecutionReadinessIssue {
    FullNodeBuild,
    LiteBackendCapabilityMissing,
    ArtifactPathMissing,
    ArtifactMissing,
    ArtifactUnreadable,
    ArtifactNotSdxlCompatible,
    ArtifactSymbolsMissing,
    ArtifactStringOwnershipUnverified,
    ArtifactShutdownUnavailable,
    BackendNotLinked,
    BridgeUnavailable,
    IntegrationRejected,
    IntegrationUnsafe,
    IntegrationFeedNotReady,
    WorkerQueueOwnerMissing,
    SyncLoopOwnerMissing,
    StartSyncExecutionMissing,
    SyncStatusExecutionMissing,
    CancellationPathMissing,
    CancellationPending,
    ShutdownPathMissing,
    ShutdownPending,
    RetryPolicyMissing,
    RetryLimitReached,
    UserVisibleStatusMissing,
    RecoveryClearMissing,
    RecoveryRescanMissing,
    RecoveryRestartMissing,
    RecoveryUserAttentionMissing,
};

struct LiteWalletSdxlArtifactSymbolsInput {
    bool walletExists = false;
    bool initializeNew = false;
    bool initializeNewFromPhrase = false;
    bool initializeExisting = false;
    bool execute = false;
    bool freeString = false;
    bool checkServerOnline = false;
    bool shutdown = false;
};

struct LiteWalletSdxlArtifactInput {
    bool pathConfigured = false;
    bool exists = false;
    bool readable = false;
    bool sdxlCompatible = false;
    std::string artifactPath;
    std::string versionLabel;
    LiteWalletSdxlArtifactSymbolsInput symbols;
};

struct LiteWalletLinkedBackendReadinessInput {
    bool linked = false;
    bool bridgeAvailable = false;
    WalletBackendStatus status;
    std::string bridgeUnavailableReason;
};

struct LiteWalletSyncExecutionOwnershipInput {
    bool workerQueueOwnerReady = false;
    bool syncLoopOwnerReady = false;
    bool startSyncExecutionReady = false;
    bool syncStatusPollingReady = false;
    bool userVisibleStatusReady = false;
};

struct LiteWalletSyncExecutionCancellationReadinessInput {
    bool cancellationPathReady = false;
    bool cancellationRequested = false;
    bool cancellationComplete = false;
};

struct LiteWalletSyncExecutionShutdownReadinessInput {
    bool shutdownHookReady = false;
    bool shutdownRequested = false;
    bool shutdownComplete = false;
};

struct LiteWalletSyncExecutionRetryReadinessInput {
    bool retryPolicyReady = false;
    bool retryRequested = false;
    std::size_t attempt = 0;
    std::size_t maxAttempts = 0;
};

struct LiteWalletSyncExecutionRecoveryReadinessInput {
    bool clearActionReady = false;
    bool rescanActionReady = false;
    bool restartSyncActionReady = false;
    bool userAttentionPathReady = false;
};

struct LiteWalletSyncExecutionReadinessInput {
    WalletCapabilities capabilities;
    LiteWalletSdxlArtifactInput artifact;
    LiteWalletLinkedBackendReadinessInput backend;
    LiteWalletSyncExecutionOwnershipInput ownership;
    LiteWalletSyncExecutionCancellationReadinessInput cancellation;
    LiteWalletSyncExecutionShutdownReadinessInput shutdown;
    LiteWalletSyncExecutionRetryReadinessInput retry;
    LiteWalletSyncExecutionRecoveryReadinessInput recovery;
    LiteWalletSyncAppRefreshIntegrationResult integrationReport;
};

struct LiteWalletSyncExecutionReadinessOptions {
    bool requireLiteBuild = true;
    bool requireLiteBackendCapability = true;
    bool requireValidatedArtifact = true;
    bool requireLinkedBackend = true;
    bool requireBridgeAvailable = true;
    bool requireIntegrationFeedReady = true;
    bool requireWorkerQueueOwner = true;
    bool requireSyncLoopOwner = true;
    bool requireStartSyncExecution = true;
    bool requireSyncStatusPolling = true;
    bool requireCancellationPath = true;
    bool requireShutdownHook = true;
    bool requireRetryPolicy = true;
    bool requireUserVisibleStatus = true;
    bool requireRecoveryExecutionReadiness = true;
};

struct LiteWalletSyncExecutionEnablementPlan {
    bool readyToEnable = false;
    bool startSyncExecutionEnabled = false;
    bool syncStatusPollingEnabled = false;
    bool workerQueueEnqueued = false;
    std::string startSyncCommand;
    std::string syncStatusCommand;
    std::string workerQueueLane;
    LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
};

struct LiteWalletSyncExecutionReadinessIssueInfo {
    LiteWalletSyncExecutionReadinessIssue issue = LiteWalletSyncExecutionReadinessIssue::FullNodeBuild;
    std::string message;
};

struct LiteWalletSyncExecutionReadinessResult {
    bool ok = false;
    bool dryRunOnly = true;
    bool noNetwork = true;
    bool noBridgeCalls = true;
    bool noSyncStarted = true;
    bool noSyncStatusPolled = true;
    bool noWalletPersistence = true;
    bool stateMutationAllowed = false;
    bool stateMutated = false;
    bool walletStateWritten = false;
    bool workerQueueEnqueued = false;

    bool liteBuildAccepted = false;
    bool artifactAccepted = false;
    bool backendLinkedAccepted = false;
    bool bridgeAccepted = false;
    bool integrationAccepted = false;
    bool workerQueueOwnerAccepted = false;
    bool syncLoopOwnerAccepted = false;
    bool startSyncExecutionReady = false;
    bool syncStatusPollingReady = false;
    bool cancellationReady = false;
    bool shutdownReady = false;
    bool retryReady = false;
    bool userVisibleStatusReady = false;
    bool recoveryExecutionReady = false;

    bool syncExecutionCouldStart = false;
    bool syncStatusPollingCouldStart = false;
    bool executionWouldUseBridge = false;
    bool integrationFeedReady = false;
    bool recoveryRequired = false;
    bool cancellationRequired = false;
    bool shutdownRequired = false;
    bool retryRequired = false;
    bool futureClearRequired = false;
    bool futureRescanRequired = false;
    bool futureRestartSyncRequired = false;
    bool requiresUserAttention = false;

    LiteWalletSyncExecutionReadinessStatus status = LiteWalletSyncExecutionReadinessStatus::WaitingForLiteBuild;
    WalletCapabilities capabilities;
    WalletBackendStatus backendStatus;
    LiteWalletSyncAppRefreshIntegrationResult integrationReport;
    LiteWalletSyncExecutionEnablementPlan enablementPlan;
    std::vector<LiteWalletSyncExecutionReadinessIssueInfo> issues;
    std::string error;
};

const char* liteWalletSyncExecutionReadinessStatusName(
    LiteWalletSyncExecutionReadinessStatus status);
const char* liteWalletSyncExecutionReadinessIssueName(
    LiteWalletSyncExecutionReadinessIssue issue);

LiteWalletSyncExecutionReadinessResult evaluateLiteWalletSyncExecutionReadiness(
    const LiteWalletSyncExecutionReadinessInput& input,
    LiteWalletSyncExecutionReadinessOptions options = {});

class LiteWalletSyncExecutionReadinessPlanner {
public:
    explicit LiteWalletSyncExecutionReadinessPlanner(
        LiteWalletSyncExecutionReadinessOptions options = {});

    LiteWalletSyncExecutionReadinessResult evaluate(
        const LiteWalletSyncExecutionReadinessInput& input) const;

private:
    LiteWalletSyncExecutionReadinessOptions options_;
};

} // namespace dragonx::wallet