#pragma once

#include "lite_wallet_state_apply_plan.h"

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

namespace dragonx::wallet {

enum class LiteWalletStateApplyExecutionStatus {
    Disabled,
    Rejected,
    ImplementationMissing,
};

enum class LiteWalletStateApplyExecutionIssue {
    InvalidPlan,
    MutablePlanRejected,
    StateMutationDisabled,
    StateMutationImplementationMissing,
};

struct LiteWalletStateApplyExecutorOptions {
    bool requestStateMutation = false;
};

struct LiteWalletStateApplyExecutionIssueInfo {
    LiteWalletStateApplyExecutionIssue issue = LiteWalletStateApplyExecutionIssue::StateMutationDisabled;
    std::string message;
};

struct LiteWalletStateApplyExecutionResult {
    bool ok = false;
    bool planAccepted = false;
    bool attempted = false;
    bool applied = false;
    bool stateMutated = false;
    bool dryRunOnly = true;
    bool noNetwork = true;
    bool stateMutationRequested = false;
    bool stateMutationAllowed = false;
    bool applyImplemented = false;

    LiteWalletStateApplyExecutionStatus status = LiteWalletStateApplyExecutionStatus::Disabled;
    std::size_t fieldPlanCount = 0;
    std::size_t collectionPlanCount = 0;
    std::size_t plannedChangeCount = 0;
    std::size_t planIssueCount = 0;
    std::vector<LiteWalletStateApplyExecutionIssueInfo> issues;
    std::string error;
};

const char* liteWalletStateApplyExecutionStatusName(LiteWalletStateApplyExecutionStatus status);
const char* liteWalletStateApplyExecutionIssueName(LiteWalletStateApplyExecutionIssue issue);

LiteWalletStateApplyExecutionResult executeLiteWalletStateApplyPlan(
    const LiteWalletStateApplyPlan& plan,
    LiteWalletStateApplyExecutorOptions options = {});

class LiteWalletStateApplyExecutor {
public:
    explicit LiteWalletStateApplyExecutor(LiteWalletStateApplyExecutorOptions options = {});

    LiteWalletStateApplyExecutionResult execute(const LiteWalletStateApplyPlan& plan) const;

private:
    LiteWalletStateApplyExecutorOptions options_;
};

} // namespace dragonx::wallet