const { HDPrivateKey, PrivateKey, Unit } = require('bitcore-lib')
const { TemplateWarehouse, Compiler, Transaction } = require('@asimovdev/asimovjs')
const readlineSync = require('readline-sync')
const colors = require('colors')
const storage = require('./storage')
const { rpc, request } = require('./rpc')
const path = require('path')
const jq = require('node-jq')
const { consoleJSON } = require('./console')

module.exports = {
  send: function(address, amount, asset, data, type, gasLimit, feeValue, feeType) {

    if (!address) {
      console.log(colors.yellow('please specify the destination address'))
      return
    }

    if (!amount) {
      console.log(colors.yellow('the amount should be larger than 0'))
      return
    }

    let totalAmount = amount
    if (feeType == asset) {
      totalAmount += feeValue
    }

    let accounts = storage.getAccount()
    let addresses = [];
    accounts.forEach(a => {
      addresses.push(a.address)
    })

    rpc.getUtxoByAddress({
      addresses: addresses,
      asset: asset
    }).then(res => {

      let total = 0
      let inputs = []
      let keys = []

      res.forEach(u => {
        let sataoshi = Unit.fromBTC(u.amount).toSatoshis()
        if (total < totalAmount) {
          total += sataoshi
          u.amount = sataoshi.toString()
          inputs.push(u)
          accounts.forEach(a => {
            if (a.address == u.address) {
              keys.push(a.pk)
            }
          })
        }
      })

      if (!inputs.length || total < totalAmount) {
        console.log(colors.warn('not enough utxo!'))
        return
      }
      let outputs = [{
        address: address,
        amount: amount.toString(),
        assets: asset,
        data: data,
        contractType: type
      }]
      if (total - amount) {
        outputs.push({
          address: inputs[0].address,
          amount: (total - totalAmount).toString(),
          assets: asset,
          data: data,
          contractType: type
        })
      }

      if (fee.asset != asset) {
        return new Promise((resolv, reject) => {
          rpc.getUtxoByAddress({
            addresses: addresses,
            asset: fee.asset
          }).then(res => {
            let total = 0

            res.forEach(u => {
              let sataoshi = Unit.fromBTC(u.amount).toSatoshis()
              if (total < feeValue) {
                total += sataoshi
                u.amount = sataoshi.toString()
                inputs.push(u)
                accounts.forEach(a => {
                  if (a.address == u.address) {
                    keys.push(a.pk)
                  }
                })
              }
            })

            if (!inputs.length || total < feeValue) {
              console.log(colors.warn('not enough utxo as fee'))
              reject('not enough utxo as fee')
            }

            outputs.push({
              address: inputs[0].address,
              amount: (total - feeValue).toString(),
              assets: feeType,
              data: "",
              contractType: ""
            })

            let tx = new Transaction({
              inputs: inputs,
              outputs: outputs,
              gasLimit: gasLimit
            })
            let rawTx = tx.sign(keys).toHex()
            rpc.sendRawTransaction(rawTx).then(res => {
              resolve(res)
            }).catch(e => {
              reject(e)
            })

          })
        })

      } else {
        let tx = new Transaction({
          inputs: inputs,
          outputs: outputs,
          gasLimit: gasLimit
        })

        let rawTx = tx.sign(keys).toHex()

        return rpc.sendRawTransaction(rawTx)
      }

    }).catch(e => {
      console.log(colors.red(e))
    })

  },
  detail: function(txId) {
    request('getRawTransaction', [txId, true, true]).then(res => {
      console.log(colors.green('success!'))
      consoleJSON(res)
    }).catch(e => {
      console.log(colors.red(e))
    })

  }
}
