const Sub = require('../models/sub').Sub;
const latestSubs = require('../models/sub').latestSubs;
const subsPerPage = require('../models/sub').subsPerPage;

exports.addSubs = (req, res, next) => {
    Sub.findByEm(req.body.email)
        .then(sub => { // NOTE: should probably refactor this code, likely using more promises and longer .then() chain
            console.log('Another sub test: ', sub);
            if (sub !== null) {
                console.log('entry already found - should not add');
                //res.redirect('/subs');
                res.render('index', {
                    pageHead: 'Homepage',
                    pageTitle: 'intro for homepage',
                    pageIntro: 'ERROR: email address already registered - please enter a unique email address that has not already been registered.',
                    isLoggedIn: req.session.isLoggedIn // req.get('Cookie') == undefined ? false : req.get('Cookie').split('=')[1]
                });
            } else {
                console.log('no email address entry already found - can add');
                const newSub = new Sub(req.body.name, req.body.email, req.body.tag); // name = name of form in index.ejs
                console.log('new sub: ', newSub);

                newSub.save() // verified status initially unverified; changes if click email url
                    .then(result => {
                        console.log('result: ', result, 'sub _id: ', result.ops[0]._id, 'sub authCode: ', result.ops[0].authCode);

                        newSub.sendVerificationEmail(req.body.email, req.protocol, req.get("host"), result.ops[0]._id, result.ops[0].authCode) // sends verification email only
                            .then(result => {
                                console.log('sendVerificationEmail() result: ', result);
                            })
                            .catch(err => {
                                console.log(err);
                            });
                    })
                    .catch(err => {
                        console.log(err);
                    });

                res.render('sub-new-pending', { // change to something like 'new sub pending verification - check your email'
                    pageHead: 'New Subscriber', // used as pageHead token in subs.ejs
                    pageTitle: 'New Subscriber Add Pending',
                    pageIntro: 'Here is the latest entry - check email (and junk inbox) and click link to finish subscription.',
                    subscribers: [latestSubs[latestSubs.length - 1]], // pass latest sub array into object
                    isLoggedIn: req.session.isLoggedIn // req.get('Cookie') == undefined ? false : req.get('Cookie').split('=')[1]
                });
            }
        })
        .catch(err => {
            console.log(err);
        })
}

exports.renderIndex = (req, res, next) => {
    res.render('index', {
        pageHead: 'Homepage',
        pageTitle: 'intro for homepage',
        pageIntro: 'This is a demo application that demonstrates adding email entries into a database using NodeJS, NoSQL, mongoDB, ExpressJS, EJS templating, middleware routing, OOP and promises, using the MVC framework, and form validation, duplicate email entry prevention and 404 errors. Just enter a name and email address (that has not already been entered) into the box and submit the form. An email containing a verification link will automatically be sent to the email address submitted whereby clicking the link will verify the subscriber.',
        isLoggedIn: req.session.isLoggedIn // req.get('Cookie') == undefined ? false : req.get('Cookie').split('=')[1]
    });
    //res.redirect('/subs'); // go to /subs after submitting form - this does nothing... why did I put it here?
}

exports.subsChunk = (req, res, next) => {
    const page = +req.query.page || 1; // + converts into a number rather than string; make it page 1 if no query param so /subs is correct
    let totalSubs;

    Sub.fetchAll()
        .then(numSubs => { // NOTE: should probably refactor this code, likely using more promises and longer .then() chain
            totalSubs = numSubs.length;
            console.log('totalSubs 1st log: ', totalSubs);

            let lastPage = Math.ceil(totalSubs / subsPerPage);

            Sub.fetchChunk(page)
                .then(subs => {
                    //console.log('page: ', page, '1: ', 1);
                    console.log('totalSubs 2nd log: ', totalSubs,
                        'currentPage: ', page,
                        'hasNextPage: ', subsPerPage * page < totalSubs,
                        'hasPreviousPage: ', page > 1,
                        'nextPage: ', page + 1,
                        'previousPage: ', page - 1,
                        'subsPerPage: ', subsPerPage);
                    // console.log('lastPage: ', lastPage);

                    console.log('totalSubs wtf log: ', totalSubs);
                    console.log('lastPage wtf log: ', lastPage);

                    res.render('subs', {
                        pageHead: 'Some Subscribers',
                        pageTitle: 'Viewing Some Subscribers',
                        pageIntro: 'This is a list of some entries.',
                        subscribers: subs,
                        totalSubs: totalSubs,
                        currentPage: page,
                        hasNextPage: subsPerPage * page < totalSubs,
                        hasPreviousPage: page > 1,
                        nextPage: page + 1,
                        previousPage: page - 1,
                        lastPage: Math.ceil(totalSubs / subsPerPage),
                        isLoggedIn: req.session.isLoggedIn // req.get('Cookie') == undefined ? false : req.get('Cookie').split('=')[1]
                    });

                    console.log('totalSubs: ', totalSubs);
                    console.log('subsPerPage: ', subsPerPage);
                    console.log('Math.ceil(totalSubs / subsPerPage): ', Math.ceil(totalSubs / subsPerPage));
                    console.log('lastPage: ', lastPage);
                })
                .catch(err => {
                    console.log(err);
                })
        })
        .catch(err => {
            console.log('error...? ', err);
        })
}

exports.viewSub = (req, res, next) => {
    console.log('req.params: ', req.params, 'req.params._id: ', req.params._id);
    Sub.findById(req.params._id)
        .then(sub => {
            console.log('final sub: ', sub);
            console.log('_id: ', sub._id);
            res.render('sub', {
                pageHead: 'Single Subscriber',
                pageTitle: 'Viewing a Single Subscriber',
                pageIntro: 'This is a specific subscriber.',
                name: sub.name,
                email: sub.email,
                tag: sub.tag,
                subDate: sub.subDate,
                verificationStatus: sub.verified,
                id: sub._id,
                isLoggedIn: req.session.isLoggedIn // req.get('Cookie') == undefined ? false : req.get('Cookie').split('=')[1]
            });
        })
        .catch(err => {
            console.log(err);
        })
}

exports.postDeleteSub = (req, res, next) => {
    const id = req.body.id;
    Sub.deleteById(id)
        .then(() => {
            console.log('deleted subscriber');
            res.redirect('/subs');
        })
        .catch(err => console.log(err));
}

exports.postRenameSub = (req, res, next) => {
    const id = req.body.id,
        newName = req.body.name;

    Sub.findById(id)
        .then(sub => {
            Sub.prototype.changeName(id, newName)
                .then(() => {
                    console.log('updated sub name');
                    res.redirect('/subs');
                })
                .catch(err => console.log(err))
        })
        .catch(err => console.log(err))
}

exports.verifySub = (req, res, next) => {
    /*
    IF STRING WAS, E.G., /sub-verified?id=someid&auth=somenumbers
    */
    const id = req.query.id;
    const auth = req.query.auth;

    console.log('req.query.id: ', id, 'req.query.auth: ', auth);
    console.log('req.query.id: ', id, 'Number(req.query.auth): ', Number(req.query.auth));

    if (id == undefined || auth == undefined) {
        console.log('render sub error page: not verified');
        res.render('sub-not-verified', {
            pageHead: 'Error with Email Address Verification',
            pageTitle: 'Error - Email Address Failed to Verify',
            pageIntro: 'Error - email address not verified. ID or auth parameter undefined.',
            errorDetails: 'Error details: incorrect ID or auth code passed into URL',
            isLoggedIn: req.session.isLoggedIn // req.get('Cookie') == undefined ? false : req.get('Cookie').split('=')[1]
        });
        // res.redirect instead?
    } else {
        Sub.findByIdAndAuth(id, auth)
            .then(sub => { // NOTE: consider refactoring this code, perhaps using more promises and longer .then() chain
                console.log('fba sub: ', sub, 'id: ', id, 'auth: ', auth); // found successfully

                if (sub.verified) {
                    console.log('sub already verified');
                    res.render('sub-verified', {
                        pageHead: 'Subscriber Verification',
                        pageTitle: 'Email Address Already Verified',
                        pageIntro: 'Subscriber ALREADY verified.',
                        name: sub.name,
                        email: sub.email,
                        isLoggedIn: req.session.isLoggedIn // req.get('Cookie') == undefined ? false : req.get('Cookie').split('=')[1]
                    });
                } else if (auth == sub.authCode) {
                    console.log('truee');
                    Sub.prototype.makeVerified(id)
                        .then(subb => { // why do I need subb?
                            console.log('g subb: ', subb);
                            console.log('h sub: ', sub);
                            res.render('sub-verified', {
                                pageHead: 'Subscriber Verification',
                                pageTitle: 'Verifying a Single Subscriber',
                                pageIntro: 'Subscriber verified.',
                                name: sub.name,
                                email: sub.email,
                                isLoggedIn: req.session.isLoggedIn // req.get('Cookie') == undefined ? false : req.get('Cookie').split('=')[1]
                            });
                        })
                        .catch(err => {
                            console.log(err);
                        })
                } else {
                    console.log('false - auth and id do not match');

                    res.render('sub-not-verified', {
                        pageHead: 'Error with Email Address Verification',
                        pageTitle: 'Error - Email Address Failed to Verify',
                        pageIntro: 'Error - email address not verified. ID and auth parameters do not match.',
                        errorDetails: 'Error details: ID and auth parameters in URL do not match. The email address associated with that ID does not have that auth code.',
                        isLoggedIn: req.session.isLoggedIn // req.get('Cookie') == undefined ? false : req.get('Cookie').split('=')[1]
                    });
                }
            })
            .catch(err => {
                console.log(err);
            })
    }
}

/* APIs */
exports.getSubsAPI = (req, res, next) => {
    Sub.fetchAll()
        .then(subs => {
            res.status(200).json({
                subs
            })
        })
        .catch(err => {
            console.log(err);
        })
};

//https://codepen.io/ns91/pen/VwejXjw?editors=1010
exports.postSubAPI = (req, res, next) => {
    const name = req.body.name,
        email = req.body.email,
        tag = req.body.tag;

    res.status(201).json({
        message: 'Sub details sent successfully',
        post: {
            id: new Date().toISOString(),
            name: name,
            email: email,
            tag: tag,
            subDate: function () {
                const d = new Date(),
                    fullDate = d.getDate() + ' ' + d.toLocaleString('default', {
                        month: 'long'
                    }) + ' ' + d.getFullYear();
                return fullDate
            }(),
            verified: false,
            authCode: Math.floor(Math.random() * 999) + 1
        }
    });
};