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

#include "wallet_state.h"
#include "../util/text_format.h"   // util::formatClockDateTime (app-wide 24h/12h clock)
#include <algorithm>
#include <ctime>
#include <sstream>
#include <iomanip>

namespace dragonx {

std::vector<size_t> sortedSpendableAddressIndices(const std::vector<AddressInfo>& addresses,
                                                  bool requirePositiveBalance)
{
    std::vector<size_t> indices;
    indices.reserve(addresses.size());
    for (size_t i = 0; i < addresses.size(); ++i) {
        const auto& address = addresses[i];
        if (!address.isSpendable()) continue;
        // Rank/filter by the CONFIRMED balance — an address holding only 0-conf change can't be sent from.
        if (requirePositiveBalance && address.spendableBalance <= 0.0) continue;
        indices.push_back(i);
    }

    std::sort(indices.begin(), indices.end(), [&](size_t lhs, size_t rhs) {
        return addresses[lhs].spendableBalance > addresses[rhs].spendableBalance;
    });
    return indices;
}

int bestSpendableAddressIndex(const std::vector<AddressInfo>& addresses)
{
    int bestIndex = -1;
    double bestBalance = 0.0;
    for (size_t i = 0; i < addresses.size(); ++i) {
        if (addresses[i].isSpendable() && addresses[i].spendableBalance > bestBalance) {
            bestBalance = addresses[i].spendableBalance;
            bestIndex = static_cast<int>(i);
        }
    }
    return bestIndex;
}

std::string TransactionInfo::getTimeString() const
{
    if (timestamp == 0) return "Unknown";
    return util::formatClockDateTime(timestamp);
}

std::string TransactionInfo::getTypeDisplay() const
{
    if (type == "send") return "Sent";
    if (type == "receive") return "Received";
    if (type == "mined" || type == "generate" || type == "immature") return "Mined";
    return type;
}

std::string PeerInfo::getConnectionTime() const
{
    if (conntime == 0) return "Unknown";
    
    int64_t now = std::time(nullptr);
    int64_t diff = now - conntime;
    
    if (diff < 60) return std::to_string(diff) + "s";
    if (diff < 3600) return std::to_string(diff / 60) + "m";
    if (diff < 86400) return std::to_string(diff / 3600) + "h";
    return std::to_string(diff / 86400) + "d";
}

std::string BannedPeer::getBannedUntilString() const
{
    if (banned_until == 0) return "Never";
    return util::formatClockDateTime(banned_until);
}

} // namespace dragonx
