#pragma once

#include "lite_wallet_refresh_readiness_policy.h"

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

namespace dragonx::wallet {

enum class LiteWalletAppRefreshOrchestrationStatus {
    Queued,
    Skipped,
    Blocked,
};

enum class LiteWalletAppRefreshScheduleTrigger {
    Periodic,
    Manual,
    Startup,
    WalletOpened,
};

enum class LiteWalletAppRefreshOrchestrationIssue {
    ReadinessRejected,
    UnsafeReadinessReport,
    SchedulerDisabled,
    RefreshNotDue,
    RefreshAlreadyQueued,
    RefreshInProgress,
    QueuePressure,
};

struct LiteWalletAppRefreshScheduleInput {
    LiteWalletAppRefreshScheduleTrigger trigger = LiteWalletAppRefreshScheduleTrigger::Periodic;
    bool schedulerEnabled = true;
    bool refreshDue = false;
    bool forceRefresh = false;
    bool refreshAlreadyQueued = false;
    bool refreshInProgress = false;
    std::size_t queueDepth = 0;
    std::size_t maxQueueDepth = 0;
};

struct LiteWalletAppRefreshOrchestratorOptions {
    bool requireEligibleReadiness = true;
    std::size_t maxQueueDepth = 0;
};

struct LiteWalletAppRefreshOrchestrationIssueInfo {
    LiteWalletAppRefreshOrchestrationIssue issue = LiteWalletAppRefreshOrchestrationIssue::ReadinessRejected;
    std::string message;
};

struct LiteWalletAppRefreshOrchestrationResult {
    bool ok = false;
    bool wouldQueueRefresh = false;
    bool skipped = false;
    bool blocked = false;
    bool readinessAccepted = false;
    bool schedulerAccepted = false;
    bool dryRunOnly = true;
    bool noNetwork = true;
    bool stateMutationRequested = false;
    bool stateMutationAllowed = false;
    bool stateMutated = false;
    bool walletStateWritten = false;

    bool schedulerEnabled = true;
    bool refreshDue = false;
    bool forceRefresh = false;
    bool refreshAlreadyQueued = false;
    bool refreshInProgress = false;
    std::size_t queueDepth = 0;
    std::size_t maxQueueDepth = 0;

    LiteWalletAppRefreshOrchestrationStatus status = LiteWalletAppRefreshOrchestrationStatus::Blocked;
    LiteWalletAppRefreshScheduleTrigger trigger = LiteWalletAppRefreshScheduleTrigger::Periodic;
    LiteWalletRefreshRouteKind route = LiteWalletRefreshRouteKind::Unavailable;
    LiteWalletRefreshReadinessResult readinessResult;
    std::vector<LiteWalletAppRefreshOrchestrationIssueInfo> issues;
    std::string error;
};

const char* liteWalletAppRefreshOrchestrationStatusName(
    LiteWalletAppRefreshOrchestrationStatus status);
const char* liteWalletAppRefreshScheduleTriggerName(
    LiteWalletAppRefreshScheduleTrigger trigger);
const char* liteWalletAppRefreshOrchestrationIssueName(
    LiteWalletAppRefreshOrchestrationIssue issue);

LiteWalletAppRefreshOrchestrationResult orchestrateLiteWalletAppRefresh(
    const LiteWalletRefreshReadinessResult& readiness,
    const LiteWalletAppRefreshScheduleInput& schedule,
    LiteWalletAppRefreshOrchestratorOptions options = {});

class LiteWalletAppRefreshOrchestrator {
public:
    explicit LiteWalletAppRefreshOrchestrator(LiteWalletAppRefreshOrchestratorOptions options = {});

    LiteWalletAppRefreshOrchestrationResult evaluate(
        const LiteWalletRefreshReadinessResult& readiness,
        const LiteWalletAppRefreshScheduleInput& schedule) const;

private:
    LiteWalletAppRefreshOrchestratorOptions options_;
};

} // namespace dragonx::wallet