import { ApiPromise, WsProvider } from '@polkadot/api'
const {
    TypeExtensions,
    RpcExtensions,
    SignedExtensions,
} = require('@aetheras/agencejs-extensions')


// #HACK, SubstrateV3 stable vs V3+ master diverged in that the new model includes "sufficients"
// Since we are pinning to subtrate v3 stable, we've hacked this
const SUBSTRATEV3_ACCOUNTINFO_TYPE_HACK = {
    ...TypeExtensions,
    AccountInfo: 'AccountInfoWithDualRefCount',
    // 		{
    //         nonce: 'Index',
    //         consumers: 'RefCount',
    //         providers: 'RefCount',
    //         // sufficients: 'RefCount',
    //         data: 'AccountData',
    //     },
}

async function createReady(url: string) {
    // Initialize the provider to connect to the local node
    const wsProvider = new WsProvider(url)

    // Create the API and wait until ready
    const api = await ApiPromise.create({
        provider: wsProvider,
        // types: TypeExtensions,
        types: SUBSTRATEV3_ACCOUNTINFO_TYPE_HACK,
        rpc: RpcExtensions,
        signedExtensions: SignedExtensions,
    })
    return api
}

function create(url: string, signer: any) {
    // Initialize the provider to connect to the local node
    const wsProvider = new WsProvider(url)

    // Create unready API
    return new ApiPromise({
        provider: wsProvider,
        signer: signer,
        // types: TypeExtensions,
        types: SUBSTRATEV3_ACCOUNTINFO_TYPE_HACK,
        rpc: RpcExtensions,
        signedExtensions: SignedExtensions,
    })
}

async function getChainInfo(api: any) {
    const [properties, systemChain, nodeName, nodeVer] = await Promise.all([
        api.rpc.system.properties(),
        api.rpc.system.chain(),
        api.rpc.system.name(),
        api.rpc.system.version(),
    ])
    return {
        properties,
        systemChain,
        nodeName,
        nodeVer,
    }
}

async function getNodeInfo(api: any) {
    const [blockNumber, health, peers, extrinsics] = await Promise.all([
        api.derive.chain.bestNumber(),
        api.rpc.system.health(),
        api.rpc.system.peers(),
        api.rpc.author.pendingExtrinsics(),
    ])
    return [blockNumber, health, peers, extrinsics]
}

module.exports = {
    create,
    createReady,
    getChainInfo,
    getNodeInfo,
    WsProvider,
    TypeExtensions,
}
