const express = require('express');
const morgan = require('morgan');
const mongoose = require('mongoose');
const txns = require('./models/txns');
const Web3 = require("web3");

// express app
const app = express();
// app.use(express.static(__dirname + '/public'));
app.listen(3000);

// connect to mongodb & listen for requests
const dbURI = "mongodb+srv://redkirti:Strong1234@cluster0.4oandf8.mongodb.net/orderbook?retryWrites=true&w=majority";

const connectionParams={
    useNewUrlParser: true,
    useUnifiedTopology: true 
}
mongoose.connect(dbURI,connectionParams)
    .then( () => {
        console.log('Connected to the database ')
        console.log('Listening on Port 3000')
    })
    .catch( (err) => {
        console.error(`Error connecting to the database. n${err}`);
    })



    const ethNetwork = 'https://goerli.infura.io/v3/069b7d73ec604e52a5092610c9f410ea';
    const web3 = new Web3(new Web3.providers.HttpProvider(ethNetwork));
    const web3ont = new Web3(new Web3.providers.HttpProvider('https://polaris2.ont.io:10339'));
    async function func(hashlock){
            var contract = await new web3.eth.Contract([
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        },
                        {
                            "internalType": "address",
                            "name": "buyerOntAddress",
                            "type": "address"
                        }
                    ],
                    "name": "bid",
                    "outputs": [],
                    "stateMutability": "payable",
                    "type": "function"
                },
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        },
                        {
                            "internalType": "string",
                            "name": "secret",
                            "type": "string"
                        }
                    ],
                    "name": "claimEth",
                    "outputs": [],
                    "stateMutability": "nonpayable",
                    "type": "function"
                },
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        }
                    ],
                    "name": "initiateBidding",
                    "outputs": [],
                    "stateMutability": "nonpayable",
                    "type": "function"
                },
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "",
                            "type": "bytes32"
                        }
                    ],
                    "name": "orderList",
                    "outputs": [
                        {
                            "internalType": "address",
                            "name": "initiatorEthAddress",
                            "type": "address"
                        },
                        {
                            "internalType": "address",
                            "name": "buyerOntAddress",
                            "type": "address"
                        },
                        {
                            "internalType": "address",
                            "name": "buyerEthAddress",
                            "type": "address"
                        },
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        },
                        {
                            "internalType": "uint256",
                            "name": "mxbid",
                            "type": "uint256"
                        },
                        {
                            "internalType": "uint256",
                            "name": "refundTimelock",
                            "type": "uint256"
                        },
                        {
                            "internalType": "uint256",
                            "name": "bidTimelock",
                            "type": "uint256"
                        },
                        {
                            "internalType": "string",
                            "name": "secret",
                            "type": "string"
                        },
                        {
                            "internalType": "enum EthereumContract.Status",
                            "name": "status",
                            "type": "uint8"
                        }
                    ],
                    "stateMutability": "view",
                    "type": "function"
                },
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        }
                    ],
                    "name": "refundEth",
                    "outputs": [],
                    "stateMutability": "nonpayable",
                    "type": "function"
                },
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        },
                        {
                            "internalType": "address",
                            "name": "initiatorEthAddress",
                            "type": "address"
                        }
                    ],
                    "name": "setInitiatorAddr",
                    "outputs": [],
                    "stateMutability": "nonpayable",
                    "type": "function"
                }
            ], '0x8909Dff24b48790c9A0590F706Dc8f3B1709ce88');
            var x = await contract.methods.orderList('0xfb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603').call();
            var contractont = await new web3ont.eth.Contract([
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        },
                        {
                            "internalType": "string",
                            "name": "secret",
                            "type": "string"
                        }
                    ],
                    "name": "claimOnt",
                    "outputs": [],
                    "stateMutability": "nonpayable",
                    "type": "function"
                },
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        },
                        {
                            "internalType": "address",
                            "name": "initiatorEthAddress",
                            "type": "address"
                        }
                    ],
                    "name": "initiateOrder",
                    "outputs": [],
                    "stateMutability": "payable",
                    "type": "function"
                },
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "",
                            "type": "bytes32"
                        }
                    ],
                    "name": "orderList",
                    "outputs": [
                        {
                            "internalType": "address",
                            "name": "initiatorOntAddress",
                            "type": "address"
                        },
                        {
                            "internalType": "address",
                            "name": "initiatorEthAddress",
                            "type": "address"
                        },
                        {
                            "internalType": "address",
                            "name": "buyerOntAddress",
                            "type": "address"
                        },
                        {
                            "internalType": "address",
                            "name": "buyerEthAddress",
                            "type": "address"
                        },
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        },
                        {
                            "internalType": "uint256",
                            "name": "amountOnt",
                            "type": "uint256"
                        },
                        {
                            "internalType": "uint256",
                            "name": "refundTimelock",
                            "type": "uint256"
                        },
                        {
                            "internalType": "uint256",
                            "name": "initiatedTime",
                            "type": "uint256"
                        },
                        {
                            "internalType": "string",
                            "name": "secret",
                            "type": "string"
                        },
                        {
                            "internalType": "enum OntologyContract.Status",
                            "name": "status",
                            "type": "uint8"
                        }
                    ],
                    "stateMutability": "view",
                    "type": "function"
                },
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        }
                    ],
                    "name": "refundOnt",
                    "outputs": [],
                    "stateMutability": "nonpayable",
                    "type": "function"
                },
                {
                    "inputs": [
                        {
                            "internalType": "bytes32",
                            "name": "hashlock",
                            "type": "bytes32"
                        },
                        {
                            "internalType": "address",
                            "name": "buyerOntAddress",
                            "type": "address"
                        }
                    ],
                    "name": "setBuyerAddr",
                    "outputs": [],
                    "stateMutability": "nonpayable",
                    "type": "function"
                }
            ], '0xC6CD342cEba445bBfB98B9d5Da99c62B2B98CFbe');
            var y = await contractont.methods.orderList('0xfb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603').call();
            return {'hashlock':hashlock, 'amountOnt': y['amountOnt'], 'bidTimelock':x['bidTimelock']};
        }

// register view engine
app.set('view engine', 'ejs');

// middleware & static files
app.use(express.static('public'));
app.use(express.urlencoded({ extended: true}));
app.use(morgan('dev'));
app.use((req, res, next) => {
  res.locals.path = req.path;
  next();
});

app.post('/txns', (req, res) => {
    console.log(req.body);
    const txn = new txns(req.body);
    txn.save().then((result) => {
        res.send(result)
    })
    .catch((err) => {
        console.log(err);
    })
});

app.get('/txns', (req,res) => {
    txns.find().then((result) => {
        // console.log(typeof(result));
        var arr = [];
        result.forEach(async txn => {
            // console.log(txn.hashlock);
            // var obj = {'hashlock': txn.hashlock,
            //             'amountOnt': txn.amountOnt,
            //             'bidTimelock': txn.bidTimelock};
            var obj = await func(txn.hashlock);
            if(obj['amountOnt']!=""){
                arr.push(obj);
            }
            // console.log(obj);
        });
        console.log(arr);
        res.render('orderbook', {title: 'All Transactions', txns: arr});
    })
    .catch((err) => {
        console.log(err);
    })
})

app.get('/', (req, res) => {
  res.render('index');
});

// 404 page
app.use((req, res) => {
  res.status(404).render('404', { title: '404' });
});


