import {socket} from "@/socket.js";
import {useStore} from "@/store/store.js";
import {erc20Abi} from "@/blockchain/abi.js";
import {ethers} from "ethers";


// synchronous version may return null but will trigger a lookup
export function token(addr) {
    console.log('token', addr)
    if( !addr ) {
        // console.log('ignoring call to token', addr)
        return null
    }
    const s = useStore()
    if( !(addr in s.tokens) ) {
        // noinspection JSIgnoredPromiseFromCall
        getToken(addr)
        return null
    }
    return s.tokens[addr]
}


// async version doesnt return until it has a token value
export async function getToken(addr) {
    const s = useStore()
    if (!(addr in s.tokens))
        await addExtraToken(addr)
    return s.tokens[addr]
}


const _inFlightLookups = {}

export async function addExtraToken(addr) {
    if( !addr ) {
        console.log('ignoring call to add extra token', addr)
        return
    }
    if( !_inFlightLookups[addr] ) {
        _inFlightLookups[addr] = true
        const prom = new Promise((resolve) => {
            const s = useStore()
            const chainId = s.chainId
            console.log('querying token', addr)
            socket.emit('lookupToken', chainId, addr, (info) => {
                console.log('server token info', addr, info)
                if (info !== null) {
                    s.addToken(chainId, info)
                    resolve(info)
                }
                else {
                    if( s.provider===null ) {
                        console.log('warning: token lookup cancelled due to null provider', addr)
                        resolve(null)
                    }
                    else {
                        const token = new ethers.Contract(addr, erc20Abi, s.provider)
                        Promise.all( [token.symbol(), token.decimals()] ).then((symbol,decimals)=>{
                            info = {
                                address: addr,
                                symbol: symbol,
                                decimals: decimals,
                            }
                            s.addToken(chainId, info)
                            resolve(info)
                        })
                    }
                }
            })
        })
        const result = await prom
        delete _inFlightLookups[addr]
        return result
    }
}
