// Etherscan address label lookup via page scraping.
// Extension users make the requests directly to Etherscan — no proxy needed.
// This is a best-effort enrichment: network failures return null silently.

// Patterns in the page title that indicate a flagged address.
// Title format: "Fake_Phishing184810 | Address: 0x... | Etherscan"
const PHISHING_LABEL_PATTERNS = [/^Fake_Phishing/i, /^Phish:/i, /^Exploiter/i];

// Patterns in the page body that indicate a scam/phishing warning.
const SCAM_BODY_PATTERNS = [
    /used in a\s+(?:\w+\s+)?phishing scam/i,
    /used in a\s+(?:\w+\s+)?scam/i,
    /wallet\s+drainer/i,
];

/**
 * Parse the Etherscan address page HTML to extract label info.
 * Exported for unit testing (no fetch needed).
 *
 * @param {string} html - Raw HTML of the Etherscan address page.
 * @returns {{ label: string|null, isPhishing: boolean, warning: string|null }}
 */
function parseEtherscanPage(html) {
    // Extract <title> content
    const titleMatch = html.match(/<title[^>]*>([^<]+)<\/title>/i);
    let label = null;
    let isPhishing = false;
    let warning = null;

    if (titleMatch) {
        const title = titleMatch[1].trim();
        // Title: "LABEL | Address: 0x... | Etherscan" or "Address: 0x... | Etherscan"
        const labelMatch = title.match(/^(.+?)\s*\|\s*Address:/);
        if (labelMatch) {
            const candidate = labelMatch[1].trim();
            // Only treat as a label if it's not just "Address" (unlabeled addresses)
            if (candidate.toLowerCase() !== "address") {
                label = candidate;
            }
        }
    }

    // Check label against phishing patterns
    if (label) {
        for (const pat of PHISHING_LABEL_PATTERNS) {
            if (pat.test(label)) {
                isPhishing = true;
                warning = `Etherscan labels this address as "${label}" (Phish/Hack).`;
                break;
            }
        }
    }

    // Check page body for scam warning banners
    if (!isPhishing) {
        for (const pat of SCAM_BODY_PATTERNS) {
            if (pat.test(html)) {
                isPhishing = true;
                warning = label
                    ? `Etherscan labels this address as "${label}" and reports it was used in a scam.`
                    : "Etherscan reports this address was flagged for phishing/scam activity.";
                break;
            }
        }
    }

    return { label, isPhishing, warning };
}

/**
 * Fetch an address page from Etherscan and check for scam/phishing labels.
 * Returns a warning object if the address is flagged, or null.
 * Network failures return null silently (best-effort check).
 *
 * Uses the current network's explorer URL so the lookup works on both
 * mainnet (etherscan.io) and Sepolia (sepolia.etherscan.io).
 *
 * @param {string} address - Ethereum address to check.
 * @returns {Promise<{type: string, message: string, severity: string}|null>}
 */
async function checkEtherscanLabel(address) {
    try {
        // Lazy require to avoid pulling in chrome.storage at module scope
        // (which breaks unit tests that only exercise parseEtherscanPage).
        const { currentNetwork } = require("./state");
        const etherscanBase = currentNetwork().explorerUrl + "/address/";
        const resp = await fetch(etherscanBase + address, {
            headers: { Accept: "text/html" },
        });
        if (!resp.ok) return null;
        const html = await resp.text();
        const result = parseEtherscanPage(html);
        if (result.isPhishing) {
            return {
                type: "etherscan-phishing",
                message: result.warning,
                severity: "critical",
            };
        }
        return null;
    } catch {
        // Network errors are expected — Etherscan may rate-limit or block.
        return null;
    }
}

module.exports = { parseEtherscanPage, checkEtherscanLabel };
