const mongodb = require('mongodb');
const getDb = require('../util/database').getDb;
const latestSubs = []; // subs added in a new session
const sendEmail = require('../util/nodemailer').sendEmail;
let twoFactorAuth = require('../util/nodemailer').twoFactorAuth;
const subsPerPage = 5;

class Sub {
  constructor(name, email, tag) {
    this.name = name;
    this.email = email;
    this.tag = tag;
    this.subDate = function () {
      const d = new Date(),
        fullDate = d.getDate() + ' ' + d.toLocaleString('default', {
          month: 'long'
        }) + ' ' + d.getFullYear();
      return fullDate
    }();
    this.verified = false; // becomes true if subscriber clicks verification url emailed to them
    this.authCode = Math.floor(Math.random() * 999) + 1;
    latestSubs.push(this);
  }

  sendVerificationEmail(email, protocol, host, id, auth) { // send two-factor auth email
    twoFactorAuth.message = 'Visit this URL to verify your email address:<br><br><a href="' + protocol + '://' + host + '/sub-verified?id=' + id + '&auth=' + auth + '" target="_blank"  style="font-size: 18px; text-decoration: none; font-weight: bold; background-color: #13aa52; padding: .5em 1.5em; color: #fff; border-radius: 15px;">Verify Email Address</a>';

    sendEmail(email, twoFactorAuth.subject, twoFactorAuth.message);
    return (Promise.resolve(email));
  }

  save() { // saves instance to DB
    const db = getDb();
    return db.collection('subs').insertOne(this) // insert into this collection, created if doesn’t exist
      .then(result => {
        console.log('save() result: ', result);
        return result;
      })
      .catch(err => {
        console.log('error: ', err)
      });
  }

  makeVerified(id) { // changes verified property to true; maybe should be static
    const db = getDb();
    return db.collection('subs').updateOne({
        _id: new mongodb.ObjectId(id)
      }, {
        $set: {
          verified: true
        }
      })
      .then(result => {
        console.log('makeVerified() result: ', result)
      })
      .catch(err => {
        console.log('error: ', err)
      });
  }

  changeName(id, newName) { // changes name of sub
    const db = getDb();
    return db.collection('subs').updateOne({
        _id: new mongodb.ObjectId(id)
      }, {
        $set: {
          name: newName
        }
      })
      .then(result => {
        console.log('changeName() result: ', result)
      })
      .catch(err => {
        console.log('error: ', err)
      });
  }

  static fetchAll() { // fetch all subs to display on page
    const db = getDb();
    return db.collection('subs')
      .find()
      .toArray()
      .then(subs => {
        return subs;
      }).catch(err => {
        console.log('error: ', err)
      });
  }

  static fetchChunk(page) { // fetch chunk of subs for pagination
    const db = getDb();
    return db.collection('subs')
      .find()
      .skip((page - 1) * subsPerPage)
      .limit(subsPerPage)
      .toArray()
      .then(subs => {
        return subs;
      }).catch(err => {
        console.log('error: ', err)
      });
  }

  static findByEm(em) {
    const db = getDb();
    return db.collection('subs')
      .find({
        'email': em
      })
      .next()
      .then(sub => {
        console.log('sub find test: ', sub)
        return sub;
      }).catch(err => {
        console.log('error: ', err)
      });
  }

  static findById(id) { // remember db uses _id
    const db = getDb();
    return db.collection('subs')
      //.find({'_id':id}) // ERROR - fixed below...
      .find({
        _id: new mongodb.ObjectId(id)
      })
      .next()
      .then(sub => {
        console.log('sub find by id test: ', sub, 'the id: ', id)
        return sub;
      }).catch(err => {
        console.log('error: ', err)
      });
  }

  static findByIdAndAuth(id, auth) {
    const db = getDb();
    return db.collection('subs')
      .find({
        _id: new mongodb.ObjectId(id)
      }, {
        authCode: auth
      })
      .next()
      .then(sub => {
        console.log('sub find by id and auth test: ', sub)
        return sub;
      }).catch(err => {
        console.log('error: ', err)
      });
  }

  static deleteById(id) {
    const db = getDb();
    return db.collection('subs')
      .deleteOne({
        _id: new mongodb.ObjectId(id)
      })
      .then(result => {
        console.log('deleted: ', result);
      }).catch(err => {
        console.log('error: ', err)
      });
  }
}

//module.exports = Sub;
exports.Sub = Sub;
exports.latestSubs = latestSubs;
exports.subsPerPage = subsPerPage;