const { HDPrivateKey, PrivateKey } = require('bitcore-lib')
const { Address } = require('@asimovdev/asimovjs')
const readlineSync = require('readline-sync')
const colors = require('colors')
const storage = require('./storage')
const { request } = require('./rpc')
const console = require('./console')

module.exports = {
  createAccount: function(pk) {
    if (!pk) {
      pk = readlineSync.question(colors.green('input private key:'))
      if (!pk) {
        return
      }
    }

    pk = pk.replace('0x', '')
    let accounts = storage.getAccount()
    let isExist = false
    accounts.forEach(p => {
      if (p.pk == pk) {
        isExist = true

        return
      }
    });

    if (isExist) {
      console.warn('the private key is already existed!')
      return
    }

    let hdKey = new PrivateKey(pk)
    let address = new Address(hdKey.publicKey).toString()
    let pair = {
      address: address,
      pk: pk
    }
    console.success('success!')
    console.success('account address: ' + address)

    accounts.push(pair)

    storage.setAccount(accounts)
  },
  listAccount: function() {
    let accounts = storage.getAccount()
    let mainAccount = storage.getMainAccount()

    if(!accounts || accounts.length == 0) {
      console.error('No accounts!')
      return
    }
    accounts.forEach(a => {
      if (mainAccount && (mainAccount.address == a.address)) {
        console.error(a.address + '  default')
      } else {
        console.success(a.address)
      }

    })
  },
  balance: function() {
    let accounts = storage.getAccount()
    let addresses = [];
    accounts.forEach(a => {
      addresses.push(a.address)
    })
    request('getBalances', [addresses]).then(res => {
      if(!res || res.length == 0) {
        console.error('No account!')
      }
      res && res.forEach(b => {
        console.log(" ")
        console.success(b.address)
        if(!b.assets || b.assets.length == 0) {
          console.error('Account no balance!')
        }
        b.assets.forEach(a => {
          console.log('    ' + colors.green(a.asset) + ':' + colors.yellow(a.value))
        })
      })
    })
  },
  utxo: function() {
    let accounts = storage.getAccount()
    let addresses = [];
    accounts.forEach(a => {
      addresses.push(a.address)
    })
    request('getUtxoByAddress', [addresses, ""]).then(res => {
      if(!res || res.length == 0) {
        console.log('no utxo!')
      }
      res && res.forEach((u, idx) => {
        console.log(" ")
        console.log(colors.yellow('  index:  ') + colors.green(idx))
        console.log(colors.yellow('  address:  ') + colors.green(u.address))
        console.log(colors.yellow('  txid:  ') + colors.green(u.txid))
        console.log(colors.yellow('  vout:  ') + colors.green(u.vout))
        console.log(colors.yellow('  asset:  ') + colors.green(u.assets))
        console.log(colors.yellow('  amount:  ') + colors.green(u.amount))
      })

    })

  },
  use: function() {
    let accounts = storage.getAccount()
    let addresses = [];
    accounts.forEach(a => {
      addresses.push(a.address)
    })
    let index = readlineSync.keyInSelect(addresses, 'choose the account to set as default')

    if (index == -1) {
      console.success('canceled')
      return
    }
    storage.setMainAccount(accounts[index])
    console.success('success!')

  },
  getMainAccount: function() {
    return storage.getMainAccount()
  },
  del: function(addr) {
    let accounts = storage.getAccount()
    let mainAccount = storage.getMainAccount()
    let temp = []

    if(!addr || addr == '') {
      console.error('No address given!')
      return
    }

    accounts.forEach(a => {
      if (a.address !== addr) {
        temp.push(a)
      }
    });

    if (temp.length == accounts.length) {
      console.warn('account ' + addr + ' does not exist!')
    } else {
      storage.setAccount(temp)
      if (mainAccount.address == addr) {
        storage.setMainAccount(temp[0] || '')
      }

      console.success('delete account ' + addr + ' successful!')

    }
  }
}
