// The field mutations a chain switch performs, applied to a state record
// handed in rather than to the module-level `state` singleton.
//
// Split out of chainSwitch.js so the background can perform a chain switch
// without the singleton being reachable from its bundle at all. The popup
// still goes through onChainSwitch() (chainSwitch.js), which applies this to
// the singleton and saves; the background applies it to the detached record of
// its own read-modify-write (src/background/state.js).
//
// Everything here is synchronous and touches nothing but the object it is
// given: no storage, no caches, no imports beyond the network table. That is
// what makes it usable on a record that has been read fresh from storage
// microseconds earlier and is about to be written back.

const { networkById } = require("./networks");

// Switch `s` to `newNetworkId` and reset every piece of chain-specific state
// it carries. Returns the network configuration object for the new chain.
function applyChainSwitchFields(s, newNetworkId) {
    const net = networkById(newNetworkId);

    // --- core identity ---
    // Endpoints are remembered per network rather than reset to the
    // defaults, because a user who points the wallet at their own node has
    // no way to get that URL back once it is gone: overwriting it moved
    // every address and every transaction onto a third-party endpoint
    // silently and permanently.
    //
    // s.rpcUrl / s.blockscoutUrl stay the live endpoints of the active
    // network, so nothing that reads them changes. The invariant is that for
    // the ACTIVE network those two fields are authoritative and the map entry
    // may be stale (Settings writes the fields directly); for every other
    // network the map is authoritative. Snapshotting the outgoing network
    // here, before the switch, is what reconciles them.
    if (!s.networkEndpoints) s.networkEndpoints = {};
    s.networkEndpoints[s.networkId] = {
        rpcUrl: s.rpcUrl,
        blockscoutUrl: s.blockscoutUrl,
    };
    const remembered = s.networkEndpoints[net.id] || {};
    s.networkId = net.id;
    s.rpcUrl = remembered.rpcUrl || net.defaultRpcUrl;
    s.blockscoutUrl = remembered.blockscoutUrl || net.defaultBlockscoutUrl;

    // --- balance / refresh state ---
    // Reset last-refresh timestamp so the next polling cycle
    // triggers an immediate balance refresh on the new chain.
    s.lastBalanceRefresh = 0;

    // Clear per-address balances and token balances so stale data
    // from the previous chain is never displayed while the first
    // refresh on the new chain is in flight.
    for (const wallet of s.wallets || []) {
        for (const addr of wallet.addresses || []) {
            addr.balance = "0";
            addr.tokenBalances = [];
        }
    }

    // --- chain-specific caches ---
    // Token holder counts and fraud contract lists are
    // chain-specific and must not carry over.
    s.tokenHolderCache = {};
    s.fraudContracts = [];

    return net;
}

module.exports = { applyChainSwitchFields };
