const { HDPrivateKey, PrivateKey } = require('bitcore-lib')
const { TemplateWarehouse, Compiler, Contract } = require('@asimovdev/asimovjs')
const readlineSync = require('readline-sync')
const colors = require('colors')
const storage = require('./storage')
const { request, rpc } = require('./rpc')
const path = require('path');
const utils = require('../lib/utils')
let Module = require('../lib/flow_4.0.1')
const console = require('./console')

module.exports = {
  call: function(contractAddress, method, args, gasLimit, amount, asset, privateKey, feeValue, feeType) {
    if (!contractAddress) {
      console.warn('contract address is not specified!')
      return
    }

    if (!method) {
      console.warn('contract method is not specified!')
      return
    }

    if (!privateKey) {
      console.warn('private key is not specified!')
      return
    }

    let mainAccount = storage.getMainAccount()
    let caller = ''

    if (privateKey) {
      caller = utils.getAddressByPrivateKey(privateKey)
    } else if (mainAccount.pk) {
      caller = mainAccount.address
    } else {
      console.warn('no caller is found!')
      return
    }

    return new Promise((resolve, reject) => {
      rpc.getContractTemplate(contractAddress).then(res => {
        let templateName = res.template_name
        let category = res.template_type

        rpc.getContractTemplateInfoByName({
          category: category,
          templateName: templateName
        }).then(res => {
          let byteCode = res.byte_code
          let abi = JSON.parse(res.abi)
          let contract = new Contract({
            abi: abi,
            byteCode: byteCode,
            contractAddress: contractAddress,
            chainRpcProvider: rpc
          })

          contract.call({
            methodName: method,
            args: args,
            privateKey: privateKey,
            gasLimit: gasLimit,
            caller: caller,
            amount: amount || 0,
            asset: asset,
            contractType: 'call',
            fee: {
              amount: feeValue,
              asset: feeType
            }
          }).then(res => {
            abi.forEach(item => {
              if(item.name == method) {
                console.success('success!')
                resolve(utils.callResultConvert(item.outputs, res))
              }
            });
          }).catch(e => {
            reject(e)
          })

        }).catch(e => {
          reject(e)
        })
      }).catch(e => {
        reject(e)
      })
    })

  }
}
