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

#pragma once

#include <string>
#include <vector>

namespace dragonx {
namespace data {

/**
 * @brief Cached, file-keyed metadata for one wallet file.
 *
 * A wallet.dat on disk only reveals its size + mtime; balance and address count require the daemon
 * to have loaded it. So those are cached here after each load and shown in the wallet-files list
 * (P2) even when the wallet isn't the active one. walletIdentityHash bridges file -> per-wallet data
 * (address book, tx history) so the right caches can be selected before/after a switch.
 */
struct WalletIndexEntry {
    std::string fileName;               // plain wallet filename in the datadir (e.g. "wallet.dat")
    std::string displayName;            // user-facing name (defaults to fileName)
    std::string walletIdentityHash;     // address-derived identity of the last load; "" = unknown
    std::string scopeId;                // stable per-wallet id ("w:"+hex) for scoping contacts etc.;
                                        // generated once, never recomputed from the (mutable) address set
    double      cachedBalance = -1.0;   // last-known total balance; < 0 = unknown (never opened)
    long long   cachedAddressCount = -1;// < 0 = unknown
    long long   lastOpenedEpoch = 0;    // unix seconds of last open; 0 = never opened
    long long   sizeBytesAtLastOpen = 0;
    bool        syncedHere = false;     // loaded in this datadir before -> catch-up on switch (no full rescan)
};

/**
 * @brief Persistent wallet-files metadata index (wallets.json, in the config dir).
 *
 * Keyed by wallet file name. Populated after each load (P1b) and read by the wallet-files list (P2).
 * Also remembers extra folders the user added to scan for wallet files. Not encrypted — it holds
 * only file names + coarse metadata (no keys/addresses).
 */
class WalletIndex {
public:
    bool load();
    bool save();
    static std::string getDefaultPath();

    const std::vector<WalletIndexEntry>& entries() const { return entries_; }
    const std::vector<std::string>& extraFolders() const { return extra_folders_; }

    /**
     * @brief Insert or update the entry for e.fileName.
     * @return true if a new entry was added or any field changed (so the caller can skip save()).
     */
    bool upsert(const WalletIndexEntry& e);

    /** @brief Find the entry for a wallet file, or nullptr. */
    const WalletIndexEntry* find(const std::string& fileName) const;

    /** @brief Add/remove an extra scan folder. Returns true if the set changed. */
    bool addExtraFolder(const std::string& dir);
    bool removeExtraFolder(const std::string& dir);

private:
    std::vector<WalletIndexEntry> entries_;
    std::vector<std::string> extra_folders_;
    std::string file_path_;
};

} // namespace data
} // namespace dragonx
