#!/usr/bin/env node-localstorage

const _ = require('lodash')
const colors = require('colors');

const { request } = require('./scripts/rpc')
const account = require('./scripts/account')
const template = require('./scripts/template')
const call = require('./scripts/call')
const tx = require('./scripts/tx')
const vote = require('./scripts/vote')
let { setRpcConfig, getRpcConfig, getMainAccount } = require('./scripts/storage')
const { consoleJSON } = require('./scripts/console')
const console = require('./scripts/console')

function handlerConfigCmd(cmd, value) {
  switch (cmd) {
    case 'set-url':

      setRpcConfig({
        url: value
      })
      break;
    case 'url':
      let rpcConfig = getRpcConfig()
      console.success(rpcConfig.url)
      break;
    default:
      break
  }
  return

}


function handlerAccountCmd(cmd, options) {
  //default cmd
  //init
  //address
  //balance
  //utxo
  //list
  switch (cmd) {
    case 'create':
      let pk = options.key
      account.createAccount(pk)
      break;
    case 'list':
      account.listAccount()
      break;
    case 'balance':
      account.balance()
      break;
    case 'utxo':
      account.utxo()
      break;
    case 'use':
      account.use()
      break;
    case 'del':
      account.del(options.address)
      break;
    default:
      break;

  }
}

function handlerRpcCmd(options) {
  let method = options.method || ''
  let args = []
  try {
    args = (options.args && JSON.parse(options.args))
  } catch (e) {
    args.push(options.args)
  }

  console.warn('sending request "' + method + '" to node...')
  if (!method) {
    throw new Error('method name is empty')
  }

  request(method, args).then(res => {
    if (res !== undefined) {
      console.success('success!')
      consoleJSON(res)
    } else {
      console.error('failed!')
    }

  })
}

function handlerTemplateCmd(cmd, options) {
  let mainAccount = getMainAccount()
  let key = (options.key && options.key.replace('0x', ''))
  let gasLimit = options.gasLimit
  let category = options.category || 1
  let page = options.page || 0
  let args = []
  let feeValue = options.feeValue || 0
  let feeType = options.feeType || '000000000000000000000000'
  try {
    args = options.args && JSON.parse(options.args)
  } catch (e) {
    args = options.args || []
  }
  if (!key || mainAccount.pk) {
    key = mainAccount.pk
  } else {
    console.warn('please specify a private key or set a default account')
    return
  }

  switch (cmd) {
    case 'create':
      let promise
      if (options.deploy) {
        promise = template.createAndDeployTemplate(options.source, options.name, category, gasLimit, key, args, feeValue,
          feeType)
      } else {
        promise = template.createTemplate(options.source, options.name, category, gasLimit, key, feeValue,
          feeType)
      }

      promise.then(res => {
        let text = ""
        try {
          text = JSON.stringify(res)
        } catch (e) {
          text = res
        }
        console.success("tx hash: " + text)
        console.warn("confirming transaction, please wait ...")
      }).catch(e => {
        console.error(e)
      })

      break;
    case 'list':
      template.listTemplate(category, page)
      break;
    case 'deploy':
      template.deployTemplate(options.id, args, gasLimit, key).then(res => {
        let text = ""
        try {
          text = JSON.stringify(res)
        } catch (e) {
          text = res
        }

        console.success("tx hash: " + text)
        console.warn("confirming transaction, please wait ...")
      }).catch(e => {
        console.error(e)
      })
    default:
      break
  }
}

function handlerCallCmd(options) {
  let mainAccount = getMainAccount()
  let gasLimit = options.gasLimit
  let args = []
  let feeValue = options.feeValue || 0
  let feeType = options.feeType || '000000000000000000000000'

  try {
    args = options.args && JSON.parse(options.args)
  } catch (e) {
    args = options.args || []
  }

  let key = (options.key && options.key.replace('0x', ''))
  let amount = options.assetValue
  let asset = options.assetType || '000000000000000000000000'
  if (!key || mainAccount.pk) {
    key = mainAccount.pk
  } else {
    console.warn('please specify a private key or set a default account')
    return
  }
  call.call(options.contractAddress, options.method, args, gasLimit, amount, asset, key, feeValue, feeType).then(res => {
    console.success(res)
  }).catch(e => {
    console.error(e)
  })

}

function handlerTxCmd(cmd, options) {
  let mainAccount = getMainAccount()
  let gasLimit = options.gasLimit || 100000000
  let data = options.data || ''
  let address = options.address || ''
  let feeValue = options.feeValue || 0
  let feeType = options.feeType || '000000000000000000000000'
  let amount = options.assetValue
  let asset = options.assetType || '000000000000000000000000'
  let callType = options.callType || ''
  let fee = options.fee

  switch (cmd) {
    case 'send':
      tx.send(options.address, amount, asset, data, callType, gasLimit, feeValue, feeType).then(res => {
        console.success("tx hash: " + res)
        console.warn("confirming transaction, please wait ...")
      }).catch(e => {
        console.error(e)
      })
      break;
    case 'detail':
      //8b0dcfd88f6e89866d05c6fef435545365a3574c87f86e5f3878f9123cb260a1
      tx.detail(options.id)
      break;
    default:
      break;
  }

}

function handlerVoteCmd(options) {
  let mainAccount = getMainAccount()
  let key = (options.key && options.key.replace('0x', ''))
  let args = []
  let feeValue = options.feeValue || 0
  let feeType = options.feeType || '000000000000000000000000'
  try {
    args = options.args && JSON.parse(options.args)
  } catch (e) {
    args = options.args || []
  }

  let voteValue = options.voteVale || 0
  let voteType = options.voteType || '000000000000000000000000'
  if (!key || mainAccount.pk) {
    key = mainAccount.pk
  } else {
    console.warn('please specify a private key or set a default account')
    return
  }
  vote.vote(options.contractAddress, options.method, args, voteValue, voteType, key, feeValue,
    feeType).then(res => {
    console.success('tx hash:' + res)
  }).catch(e => {
    console.error(e)
  })
}


module.exports = {
  handlerConfigCmd: handlerConfigCmd,
  handlerAccountCmd: handlerAccountCmd,
  handlerRpcCmd: handlerRpcCmd,
  handlerCallCmd: handlerCallCmd,
  handlerTemplateCmd: handlerTemplateCmd,
  handlerTxCmd: handlerTxCmd,
  handlerVoteCmd: handlerVoteCmd
}
