// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3

#pragma once

#include "lite_client_bridge.h"
#include "wallet_backend.h"
#include "wallet_capabilities.h"

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

namespace dragonx {
namespace wallet {

// The SDXL litelib backend identifies the production chain as "main" (its mainnet
// module carries DragonX's coin params). It hard-panics on any other chain name, so
// this MUST be one of {"main","test","regtest"} — not the coin ticker.
constexpr const char* kDragonXLiteChainName = "main";
constexpr const char* kDefaultDragonXLiteServer = "https://lite.dragonx.is";

enum class LiteServerSelectionMode {
    Sticky,
    Random
};

enum class LiteConnectionAvailability {
    Ready,
    UnsupportedBuild,
    BackendUnavailable,
    BridgeUnavailable,
    NoUsableServer
};

struct LiteServerEndpoint {
    std::string url;
    std::string label;
    bool enabled = true;
};

struct LiteConnectionSettings {
    std::vector<LiteServerEndpoint> servers;
    LiteServerSelectionMode selectionMode = LiteServerSelectionMode::Sticky;
    std::string stickyServerUrl = kDefaultDragonXLiteServer;
    std::string chainName = kDragonXLiteChainName;
    std::size_t randomSelectionSeed = 0;
};

struct LiteServerSelectionResult {
    bool ok = false;
    LiteServerEndpoint server;
    std::size_t serverIndex = 0;
    bool customServer = false;
    std::string error;
};

struct LiteWalletExistsRequest {
    std::string chainName = kDragonXLiteChainName;
};

struct LiteServerHealthRequest {
    LiteServerEndpoint server;
    std::size_t serverIndex = 0;
    bool customServer = false;
};

struct LiteWalletExistsCheckResult {
    bool ok = false;
    bool attempted = false;
    bool walletExists = false;
    LiteWalletExistsRequest request;
    WalletBackendStatus status;
    std::string error;
};

struct LiteServerHealthCheckResult {
    bool ok = false;
    bool attempted = false;
    bool serverOnline = false;
    LiteServerHealthRequest request;
    WalletBackendStatus status;
    std::string error;
};

// Trims leading/trailing whitespace, returning a copy. Shared across the lite slice.
std::string liteTrimCopy(const std::string& value);
std::vector<LiteServerEndpoint> defaultDragonXLiteServers();
LiteConnectionSettings defaultLiteConnectionSettings();
bool isLiteServerUrlUsable(const std::string& serverUrl);
// True if the URL is one of the built-in official DragonX lite servers (gets a glowing outline).
bool isOfficialLiteServer(const std::string& serverUrl);
const char* liteServerSelectionModeName(LiteServerSelectionMode mode);
const char* liteConnectionAvailabilityName(LiteConnectionAvailability availability);
LiteServerSelectionResult selectLiteServer(const LiteConnectionSettings& settings);

class LiteConnectionService {
public:
    LiteConnectionService(WalletCapabilities capabilities,
                          LiteConnectionSettings settings,
                          LiteClientBridge bridge);

    const LiteConnectionSettings& settings() const { return settings_; }
    const WalletCapabilities& capabilities() const { return capabilities_; }

    LiteConnectionAvailability availability() const;
    WalletBackendStatus status() const;
    LiteServerSelectionResult selectedServer() const;
    LiteWalletExistsRequest walletExistsRequest() const;
    LiteServerHealthRequest serverHealthRequest() const;

    LiteWalletExistsCheckResult checkWalletExists();
    LiteServerHealthCheckResult checkSelectedServerHealth();

private:
    WalletBackendStatus statusFor(LiteConnectionAvailability availability,
                                  const std::string& detail = {}) const;
    WalletBackendStatus bridgeReadinessStatus() const;

    WalletCapabilities capabilities_;
    LiteConnectionSettings settings_;
    LiteClientBridge bridge_;
};

} // namespace wallet
} // namespace dragonx