// Price fetching with 5-minute cache, USD formatting, value aggregation.

const { getTopTokenPrices } = require("./tokenList");

const PRICE_CACHE_TTL = 300000; // 5 minutes

const prices = {};
let lastFetchedAt = 0;

async function refreshPrices() {
    // Testnet tokens have no real market value — skip price fetching
    // and clear any stale mainnet prices so the UI shows no USD values.
    const { currentNetwork } = require("./state");
    if (currentNetwork().isTestnet) {
        clearPrices();
        return;
    }
    const now = Date.now();
    if (now - lastFetchedAt < PRICE_CACHE_TTL) return;
    try {
        const fetched = await getTopTokenPrices(25);
        Object.assign(prices, fetched);
        lastFetchedAt = now;
    } catch (e) {
        // prices stay stale on error
    }
}

// Clear all cached prices and reset the fetch timestamp so the
// next refreshPrices() call will fetch fresh data.
function clearPrices() {
    for (const key of Object.keys(prices)) {
        delete prices[key];
    }
    lastFetchedAt = 0;
}

// Return the USD price for a symbol, or null on testnet / unknown.
function getPrice(symbol) {
    const { currentNetwork } = require("./state");
    if (currentNetwork().isTestnet) return null;
    return prices[symbol] || null;
}

function formatUsd(amount) {
    if (amount === null || amount === undefined || isNaN(amount)) return "";
    if (amount === 0) return "$0.00";
    if (amount < 0.01) return "< $0.01";
    return (
        "$" +
        amount.toLocaleString("en-US", {
            minimumFractionDigits: 2,
            maximumFractionDigits: 2,
        })
    );
}

function getAddressValueUsd(addr) {
    const { currentNetwork } = require("./state");
    if (currentNetwork().isTestnet) return null;
    if (!prices.ETH) return null;
    let total = 0;
    const ethBal = parseFloat(addr.balance || "0");
    total += ethBal * prices.ETH;
    for (const token of addr.tokenBalances || []) {
        const tokenBal = parseFloat(token.balance || "0");
        if (tokenBal > 0 && prices[token.symbol]) {
            total += tokenBal * prices[token.symbol];
        }
    }
    return total;
}

function getWalletValueUsd(wallet) {
    const { currentNetwork } = require("./state");
    if (currentNetwork().isTestnet) return null;
    if (!prices.ETH) return null;
    let total = 0;
    for (const addr of wallet.addresses) {
        total += getAddressValueUsd(addr);
    }
    return total;
}

function getTotalValueUsd(wallets) {
    const { currentNetwork } = require("./state");
    if (currentNetwork().isTestnet) return null;
    if (!prices.ETH) return null;
    let total = 0;
    for (const wallet of wallets) {
        total += getWalletValueUsd(wallet);
    }
    return total;
}

module.exports = {
    prices,
    refreshPrices,
    clearPrices,
    getPrice,
    formatUsd,
    getAddressValueUsd,
    getWalletValueUsd,
    getTotalValueUsd,
};
