// In browsers, use a <script> tag. In Node.js, uncomment the following line:
const xrpl = require('xrpl')
const express = require('express')

const app = express()
const port = 3000

function createWallet() {
    const wallet = xrpl.Wallet.generate("ed25519")
    return wallet;
}

//const xrplServer = 'wss://s.altnet.rippletest.net:51233'
//const xrplServer = 'ws://ripple-api1.dangnn.io:6005'
const xrplServer = 'wss://xrplcluster.com'

async function test(dstTag) {
    const client = new xrpl.Client(xrplServer)
    await client.connect()

    const response = await client.request({
        "command": "server_info",
    })

    console.log(response.result.info.validated_ledger)

    // const fund_result = await client.fundWallet()
    // const test_wallet = fund_result.wallet
    // console.log(fund_result)

    //rKkPNfowKsjU616jMfvvn2rSibtrNeh7B8 dst tag enabled
    //rtCeovN6T1wE3baFuBSdRWE4QaK9sHMGS
    //sendXrpTo(test_wallet.seed, "rtCeovN6T1wE3baFuBSdRWE4QaK9sHMGS", "1000")

    await client.disconnect()

    //await getTransactionFee()
}

test()

//http://localhost:3000/wallet/getbalance?address=rJWfCDCRGY6vr43bkTXdXq7guEAjdyQCkf
async function getBalance(address) {

    const client = new xrpl.Client(xrplServer)
    await client.connect()

    const response = await client.request({
        "command": "account_info",
        "account": address,
        "ledger_index": "validated"
    })

    await client.disconnect()

    console.log(address)
    console.log(response.result.account_data)

    let ret = {
        'balance': response.result.account_data.Balance,
        'ownerCount': response.result.account_data.OwnerCount,
    }

    return ret
}

async function getTransactionFee(fromSeed, to, amount) {
    const client = new xrpl.Client(xrplServer)
    await client.connect()

    const wallet = xrpl.Wallet.fromSeed(fromSeed)

    const prepared = await client.autofill({
        "TransactionType": "Payment",
        "Account": wallet.address,
        "Amount": amount,
        "Destination": to
    })
    await client.disconnect()
    return prepared.Fee
}


//http://localhost:3000/wallet/send?fromSeed=sEdVkTBxbtqUP7Y4Do63CbvQzarRjip&toAddr=rJWfCDCRGY6vr43bkTXdXq7guEAjdyQCkf&amount=30
async function sendXrpTo(fromSeed, to, amount, dstTag) {

    const client = new xrpl.Client(xrplServer)
    await client.connect()

    const wallet = xrpl.Wallet.fromSeed(fromSeed)

    console.log(`send xrp ${wallet.address} -> ${to}, amount: ${amount}`);

    let transaction = {
        "TransactionType": "Payment",
        "Account": wallet.address,
        "Amount": amount,
        "Destination": to,
    }

    if (dstTag != undefined) {
        transaction["DestinationTag"] = parseInt(dstTag)
    }

    const prepared = await client.autofill(transaction)
    const max_ledger = prepared.LastLedgerSequence
    console.log("Prepared transaction instructions:", prepared)
    console.log("Transaction cost:", xrpl.dropsToXrp(prepared.Fee), "XRP")
    console.log("Transaction expires after ledger:", max_ledger)

    const signed = wallet.sign(prepared)
    console.log("Identifying hash:", signed.hash)
    console.log("Signed blob:", signed.tx_blob)

    const tx = await client.submitAndWait(signed.tx_blob)
    // Check transaction results -------------------------------------------------
    console.log("Transaction result:", tx.result.meta.TransactionResult)
    const result = xrpl.getBalanceChanges(tx.result.meta)
    console.log("Balance changes:", JSON.stringify(result, null, 2))
    await client.disconnect()
    return result
}

async function getReserve() {

    const client = new xrpl.Client(xrplServer)
    await client.connect()

    const response = await client.request({
        "command": "server_info",
    })

    await client.disconnect()

    let ret = {
        'reserve_base': response.result.info.validated_ledger.reserve_base_xrp,
        'reserve_inc': response.result.info.validated_ledger.reserve_inc_xrp
    }

    return ret
}

app.use(function (err, req, res, next) {
    console.error(err);
    res.status(500).send('Something broke!');
});

app.get('/wallet/create', (req, res) => {
    const wallet = createWallet()
    const resp = {}
    resp.addr = wallet.address
    resp.seed = wallet.seed
    res.send(resp)
})

app.get('/wallet/getBalance', async (req, res) => {
    try {
        const address = req.query['address']
        const balance = await getBalance(address)
        res.send(balance)
    } catch (e) {
        res.status(400).send(e.data)
    }
})

app.get('/wallet/send', async (req, res) => {
    try {
        const fromSeed = req.query['fromSeed']
        const toAddr = req.query['toAddr']
        const amount = req.query['amount']
        const destTag = req.query['destTag']

        const result = await sendXrpTo(fromSeed, toAddr, amount, destTag)
        res.send(result)
    } catch (e) {
        console.log('hello')
        res.status(400).send(e.data)
    }
})

app.get('/wallet/getTxFee', async (req, res) => {
    try {
        const fromSeed = req.query['fromSeed']
        const toAddr = req.query['toAddr']
        const amount = req.query['amount']
        const result = await getTransactionFee(fromSeed, toAddr, amount)
        res.send(result)
    } catch (e) {
        res.status(400).send(e.data)
    }
})

app.get('/wallet/getReserve', async (req, res) => {
    try {
        const reserve = await getReserve()
        //string으로 써야함
        res.send(reserve)
    } catch (e) {
        res.status(400).send(e.data)
    }
})

app.listen(port, () => {
    console.log(`wallet server listening on port ${port}`)
})
