const fetch = require('node-fetch');
const requestWebSiteFromToken = require('../tokenUtilities').requestWebSiteFromToken;
const verify = require('../tokenUtilities').verify;
const requestSessionFromToken = require('../tokenUtilities').requestSessionFromToken;
const token2Session = require('../tokenUtilities').token2Session;

module.exports = function attachRoutes(app, config) {

    app.use((req, res, next) => {
        //console.log('use account');
        if (req.session.jwt) {
            //console.log('token');
            if (verify(req.session.jwt)) {
                next();
                return;
            } else {
                req.session.jwt = undefined;
                req.session.username = undefined;
                res.redirect('/');
                return;
            }
        } else {
            //console.log('no token');
            if (req.originalUrl === '/' || req.originalUrl === '') {
                next();
                return;
            }
    
            if (req.originalUrl === '/account/sign') {
                next();
                return;
            }
    
            if (req.originalUrl === '/us') {
                next();
                return;
            }
    
            if (req.originalUrl === '/download') {
                next();
                return;
            }
            
            if (req.originalUrl === '/plugin-info') {
                next();
                return;
            }
    
            if (req.originalUrl.indexOf('/dashboard/session/view/') !== -1 ) {
                next();
                return;
            }

            res.redirect('/');
            return;
        }
    })

    app.get('/account/sign', (req, res) => {
        res.render('account/sign.ejs', {account:req.session, kind:undefined});
    });


    app.get('/account/signout', (req, res) => {
        req.session.jwt = undefined;
        req.session.username = undefined;
        res.redirect('/');
    });

    app.post('/account/sign', (req, res) => {
        const { username , password} = req.body;
        //console.log('sign', username, password);
        sign(username, password)
            .then(token => {
                req.session.jwt = token.jwt;
                req.session.username = username;
                res.redirect('/');
            })
            .catch(reason => {
                //console.log('error', reason);
                res.render('account/sign.ejs', {account:req.session, kind:'error', message:reason})
            })
    });


    app.get('/account/account', (req, res) => {
        let webSiteList;
        let sessionList;
        requestWebSiteFromToken(req.session.jwt)
            .then(requestedWebSiteList => {
                webSiteList = requestedWebSiteList;
                return requestSessionFromToken(req.session.jwt);
            })
            .then(requestedSessionList => {
                sessionList = requestedSessionList;
                let connectionCodeList = token2Session(req.session.jwt);
                res.render('account/account.ejs', {account:req.session, connectionCodeList, webSiteList, sessionList});
            })
            .catch(e => {
                res.render('error.ejs',{account:req.session, message:'cannot read account', error:e})
            })
    });

    function signup(username, password) {
        const accountURL = 'http://' + config.account.host + ':' + config.account.port + '/account/signup';
        let bodySignup = {
            username, 
            password
        }
        let optionSignup = {
            method: 'POST',
            body:    JSON.stringify(bodySignup),
            headers: { 'Content-Type': 'application/json' },
        }
        return new Promise( (res, rej) => {
            fetch(accountURL, optionSignup)
                .then(responseAccount => {
                    if (responseAccount.ok) {
                        responseAccount.json()
                            .then(createdUsername => {
                                res(createdUsername);
                            })
                            .catch(e => {
                                rej(e);
                            })
                    } else {
                        rej({isUsernameExist: true});
                    }
                })
                .catch(e => {
                    rej(e);
                });
        });
    }

    function signin(username, password) {
        const accountURL = 'http://' + config.account.host + ':' + config.account.port + '/account/signin';
        let bodySignin = {
            username, 
            password
        }
        let optionSignin = {
            method: 'POST',
            body:    JSON.stringify(bodySignin),
            headers: { 'Content-Type': 'application/json' },
        }
        return new Promise((res, rej) => {
            fetch(accountURL, optionSignin)
                .then(responseAccount => {
                    if (responseAccount.ok) {
                        responseAccount.json()
                            .then(token => {
                                res(token);
                            })
                            .catch(e => {
                                rej(e);
                            })
                    } else {
                        rej({isUsernamePasswordWrong:true});
                    }
                })
                .catch(e => {
                    rej(e);
                });
        })
    }

    function sign(username, password) {
        return signup(username, password)
            .then(() => {
                //console.log('signup ok');
                return signin(username, password)
                    .then(token => {
                        return Promise.resolve(token);
                    })
                    .catch(signinErrorReason => {
                        return Promise.reject(signinErrorReason);
                    })
            })
            .catch(signupErrorReason => {
                //console.log('signup nok', signupErrorReason);
                if (signupErrorReason.isUsernameExist) {
                    //console.log('will signin');
                    return signin(username, password)
                        .then(token => {
                            return Promise.resolve(token);
                        })
                        .catch(signinErrorReason => {
                            return Promise.reject(signinErrorReason);
                        })
                } else {
                    return Promise.reject(reason);
                }
            })
    }

}

