import {ContractInterface, ethers} from "ethers"
import contracts from "./contracts"

declare global {
  interface Window {
    ethereum: ethers.providers.ExternalProvider | ethers.providers.JsonRpcFetchFunc | undefined;
  }
}

const getWeb3Provider = (provider = null) : Promise<ethers.providers.Web3Provider | ethers.providers.JsonRpcSigner> => {
  if (provider) return Promise.resolve(provider)
  if (window.ethereum) return Promise.resolve(new ethers.providers.Web3Provider(window.ethereum, "any"))
  return Promise.reject('no web3 provider defined')
}

const controllerAddress = (contractKey : string, web3Provider = null) => {
  return getWeb3Provider(web3Provider)
    .then(provider => {
      if ('_isSigner' in provider) return provider.provider.getNetwork()
      return provider.getNetwork()
    })
    .then(({ chainId }) => {
      return contractKey.length == 42 ? contractKey : contracts[`${chainId}`][contractKey]
    }) 
}

const initContractByAbi = (abi : ContractInterface, contractKey : string, readOnly = true, web3Provider = null) => {
  return getWeb3Provider(web3Provider)
    .then(provider => {
      const signer = readOnly ? provider : ('_isSigner' in provider ? provider : provider.getSigner())
      return controllerAddress(contractKey, web3Provider)
        .then(contract_address => new ethers.Contract(contract_address, abi, signer))
    })
}

export {
  getWeb3Provider,
  controllerAddress,
  initContractByAbi
}