import { queryClient } from '../commands/_app.js';
import { queryChainConfig } from './chainConfig.js';
import { CHAIN_LIST_URL, } from '../superchain-registry/fetchChainList.js';
import { useQuery } from '@tanstack/react-query';
import { defineChain } from 'viem';
import { mainnet, sepolia } from 'viem/chains';
import { chainConfig } from 'viem/op-stack';
import * as chains from 'viem/chains';
const viemChainById = Object.values(chains).reduce((acc, chain) => {
    acc[chain.id] = chain;
    return acc;
}, {});
const chainIdByParentChainName = {
    mainnet: mainnet.id,
    sepolia: sepolia.id,
};
export const chainListItemToChain = (config, sourceChainIdByChainId) => {
    const stringId = config.identifier.split('/')[1];
    const isMainnet = config.parent.chain === 'mainnet';
    if (viemChainById[config.chainId]) {
        const viemChain = viemChainById[config.chainId];
        if (viemChain.sourceId) {
            return viemChain;
        }
        return defineChain({
            ...viemChain,
            id: config.chainId,
            // Not all chains in viem have the sourceId specified
            sourceId: sourceChainIdByChainId[config.chainId],
        });
    }
    // TODO: Does not support custom gas tokens
    return defineChain({
        ...chainConfig,
        id: config.chainId,
        name: stringId,
        sourceId: isMainnet ? mainnet.id : sepolia.id,
        nativeCurrency: {
            name: 'Ether',
            symbol: 'ETH',
            decimals: 18,
        },
        blockExplorers: {
            default: {
                name: 'Blockscout',
                url: config.explorers[0],
            },
        },
        rpcUrls: {
            default: {
                http: [config.rpc[0]],
            },
        },
        multicall: {
            address: '0xcA11bde05977b3631167028862bE2a173976CA11',
        },
    });
};
const getQueryParams = (chainListURL) => {
    return {
        queryKey: ['chainById', chainListURL],
        queryFn: async () => {
            const chainList = await queryChainConfig();
            const sourceChainIdByChainId = chainList.reduce((acc, chain) => {
                const parentChainName = chain.parent.chain;
                // @ts-expect-error
                acc[chain.chainId] = chainIdByParentChainName[parentChainName];
                return acc;
            }, {});
            const chainByID = chainList.reduce((acc, config) => {
                const chain = chainListItemToChain(config, sourceChainIdByChainId);
                acc[chain.id] = chain;
                return acc;
            }, {});
            return chainByID;
        },
        staleTime: 1000 * 60 * 60, // 1 hour
    };
};
export const queryMappingChainById = async (chainListURL = CHAIN_LIST_URL) => {
    return queryClient.fetchQuery(getQueryParams(chainListURL));
};
export const useMappingChainById = (chainListURL = CHAIN_LIST_URL) => {
    return useQuery({
        ...getQueryParams(chainListURL),
        staleTime: Infinity, // For the duration of the CLI session, this is cached
    });
};
