#pragma once

#include "lite_sync_service.h"
#include "lite_wallet_app_refresh_orchestrator.h"

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

namespace dragonx::wallet {

enum class LiteWalletSyncAppRefreshIntegrationStatus {
    FutureWorkerQueueFeedReady,
    WaitingForLifecycle,
    WaitingForSyncPlan,
    WaitingForSyncStatus,
    WaitingForRecovery,
    WaitingForCancellation,
    RefreshNotQueued,
    WorkerQueueUnavailable,
    UnsafePlan,
};

enum class LiteWalletSyncAppRefreshIntegrationIssue {
    LifecycleNotReady,
    MissingSyncStartPlan,
    InvalidSyncStartPlan,
    SyncStartWouldExecute,
    MissingSyncStatusPlan,
    InvalidSyncStatusPlan,
    SyncStatusWouldExecute,
    MissingRecoveryDecision,
    SyncStillPolling,
    SyncRecoveryRequired,
    SyncRecoveryNeedsUserAttention,
    CancellationRequired,
    CancellationUnsupported,
    RefreshReportRejected,
    RefreshReportUnsafe,
    RefreshSkipped,
    RefreshBlocked,
    FutureWorkerQueueDisabled,
    FutureWorkerQueuePressure,
};

struct LiteWalletSyncAppRefreshLifecycleInput {
    bool ready = false;
    WalletBackendStatus status;
};

struct LiteWalletSyncAppRefreshSyncPlanInput {
    bool haveStartPlan = false;
    LiteSyncPlan startPlan;
    bool haveStatusPlan = false;
    LiteSyncPlan statusPlan;
    bool haveRecoveryDecision = false;
    LiteSyncRecoveryDecision recoveryDecision;
};

struct LiteWalletSyncAppRefreshCancellationInput {
    bool cancellationRequested = false;
    bool syncInProgress = false;
    bool cancellationSupported = false;
};

struct LiteWalletFutureWorkerQueueInput {
    bool enabled = true;
    std::size_t queueDepth = 0;
    std::size_t maxQueueDepth = 0;
    std::string laneName = "lite-app-refresh";
};

struct LiteWalletSyncAppRefreshIntegrationInput {
    LiteWalletSyncAppRefreshLifecycleInput lifecycle;
    LiteWalletSyncAppRefreshSyncPlanInput sync;
    LiteWalletSyncAppRefreshCancellationInput cancellation;
    LiteWalletFutureWorkerQueueInput futureWorkerQueue;
    LiteWalletAppRefreshOrchestrationResult refreshOrchestration;
};

struct LiteWalletSyncAppRefreshIntegrationOptions {
    bool requireLifecycleReady = true;
    bool requireSyncStartPlan = true;
    bool requireSyncStatusPlan = true;
    bool requireRecoveryDecision = true;
    bool requireSyncCompleteForRefresh = true;
    bool rejectExecutableSyncPlans = true;
    bool requireFutureWorkerQueue = true;
};

struct LiteWalletFutureWorkerQueuePlan {
    bool readyToFeed = false;
    bool wouldFeed = false;
    bool enqueued = false;
    std::string laneName;
    LiteWalletAppRefreshScheduleTrigger trigger = LiteWalletAppRefreshScheduleTrigger::Periodic;
    LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
    std::string startSyncCommand;
    std::string syncStatusCommand;
    std::size_t queueDepth = 0;
    std::size_t maxQueueDepth = 0;
};

struct LiteWalletSyncAppRefreshIntegrationIssueInfo {
    LiteWalletSyncAppRefreshIntegrationIssue issue = LiteWalletSyncAppRefreshIntegrationIssue::LifecycleNotReady;
    std::string message;
};

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

    bool lifecycleAccepted = false;
    bool syncStartPlanAccepted = false;
    bool syncStatusPlanAccepted = false;
    bool recoveryAccepted = false;
    bool cancellationAccepted = false;
    bool refreshReportAccepted = false;
    bool futureWorkerQueueFeedReady = false;
    bool wouldFeedFutureWorkerQueue = false;
    bool refreshWouldQueue = false;
    bool refreshSkipped = false;
    bool refreshBlocked = false;
    bool recoveryRequired = false;
    bool cancellationRequired = false;
    bool futureClearRequired = false;
    bool futureRescanRequired = false;
    bool futureRestartSyncRequired = false;
    bool requiresUserAttention = false;

    LiteWalletSyncAppRefreshIntegrationStatus status = LiteWalletSyncAppRefreshIntegrationStatus::WaitingForLifecycle;
    LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
    WalletBackendStatus lifecycleStatus;
    LiteSyncPlan syncStartPlan;
    LiteSyncPlan syncStatusPlan;
    LiteSyncRecoveryDecision recoveryDecision;
    LiteWalletAppRefreshOrchestrationResult refreshOrchestration;
    LiteWalletFutureWorkerQueuePlan futureWorkerQueuePlan;
    std::vector<LiteWalletSyncAppRefreshIntegrationIssueInfo> issues;
    std::string error;
};

const char* liteWalletSyncAppRefreshIntegrationStatusName(
    LiteWalletSyncAppRefreshIntegrationStatus status);
const char* liteWalletSyncAppRefreshIntegrationIssueName(
    LiteWalletSyncAppRefreshIntegrationIssue issue);

LiteWalletSyncAppRefreshIntegrationResult planLiteWalletSyncAppRefreshIntegration(
    const LiteWalletSyncAppRefreshIntegrationInput& input,
    LiteWalletSyncAppRefreshIntegrationOptions options = {});

class LiteWalletSyncAppRefreshIntegrationPlanner {
public:
    explicit LiteWalletSyncAppRefreshIntegrationPlanner(
        LiteWalletSyncAppRefreshIntegrationOptions options = {});

    LiteWalletSyncAppRefreshIntegrationResult plan(
        const LiteWalletSyncAppRefreshIntegrationInput& input) const;

private:
    LiteWalletSyncAppRefreshIntegrationOptions options_;
};

} // namespace dragonx::wallet