// Address warning module.
// Provides local and async (RPC-based) warning checks for Ethereum addresses.
// Returns arrays of {type, message, severity} objects.

const { isScamAddress } = require("./scamlist");
const { isBurnAddress } = require("./constants");
const { checkEtherscanLabel } = require("./etherscanLabels");
const { log } = require("./log");

/**
 * Check an address against local-only lists (scam, burn, self-send).
 * Synchronous — no network calls.
 *
 * @param {string} address - The target address to check.
 * @param {object} [options] - Optional context.
 * @param {string} [options.fromAddress] - Sender address (for self-send check).
 * @returns {Array<{type: string, message: string, severity: string}>}
 */
function getLocalWarnings(address, options = {}) {
    const warnings = [];
    const addr = address.toLowerCase();

    if (isScamAddress(addr)) {
        warnings.push({
            type: "scam",
            message:
                "This address is on a known scam/fraud list. Do not send funds to this address.",
            severity: "critical",
        });
    }

    if (isBurnAddress(addr)) {
        warnings.push({
            type: "burn",
            message:
                "This is a known null/burn address. Funds sent here are permanently destroyed and cannot be recovered.",
            severity: "critical",
        });
    }

    if (options.fromAddress && addr === options.fromAddress.toLowerCase()) {
        warnings.push({
            type: "self-send",
            message: "You are sending to your own address.",
            severity: "warning",
        });
    }

    return warnings;
}

/**
 * Check an address against local lists AND via RPC queries.
 * Async — performs network calls to check contract status and tx history.
 *
 * @param {string} address - The target address to check.
 * @param {object} provider - An ethers.js provider instance.
 * @param {object} [options] - Optional context.
 * @param {string} [options.fromAddress] - Sender address (for self-send check).
 * @returns {Promise<Array<{type: string, message: string, severity: string}>>}
 */
async function getFullWarnings(address, provider, options = {}) {
    const warnings = getLocalWarnings(address, options);

    let isContract = false;
    try {
        const code = await provider.getCode(address);
        if (code && code !== "0x") {
            isContract = true;
            warnings.push({
                type: "contract",
                message:
                    "This address is a smart contract, not a regular wallet.",
                severity: "warning",
            });
        }
    } catch (e) {
        log.errorf("contract check failed:", e.message);
    }

    // Skip tx count check for contracts — they may legitimately have
    // zero inbound EOA transactions.
    if (!isContract) {
        try {
            const txCount = await provider.getTransactionCount(address);
            if (txCount === 0) {
                warnings.push({
                    type: "new-address",
                    message:
                        "This address has never sent a transaction. Double-check it is correct.",
                    severity: "info",
                });
            }
        } catch (e) {
            log.errorf("tx count check failed:", e.message);
        }
    }

    // Etherscan label check (best-effort async — network failures are silent).
    // Runs for ALL addresses including contracts, since many dangerous
    // flagged addresses on Etherscan (drainers, phishing contracts) are contracts.
    try {
        const etherscanWarning = await checkEtherscanLabel(address);
        if (etherscanWarning) {
            warnings.push(etherscanWarning);
        }
    } catch (e) {
        log.errorf("etherscan label check failed:", e.message);
    }

    return warnings;
}

module.exports = { getLocalWarnings, getFullWarnings };
