const debug = require('debug')('talk:services:mailer');
const nodemailer = require('nodemailer');
const kue = require('./kue');
const path = require('path');
const fs = require('fs');
const _ = require('lodash');

const i18n = require('./i18n');

const {
  SMTP_HOST,
  SMTP_USERNAME,
  SMTP_PORT,
  SMTP_PASSWORD,
  SMTP_FROM_ADDRESS
} = require('../config');

// load all the templates as strings
const templates = {
  data: {}
};

// load the templates per request during development
templates.render = (name, format = 'txt', context) => new Promise((resolve, reject) => {

  // If we are in production mode, check the view cache.
  if (process.env.NODE_ENV === 'production') {
    if (name in templates.data && format in templates.data[name]) {
      let view = templates.data[name][format];

      return resolve(view(context));
    }
  }

  const filename = path.join(__dirname, 'email', [name, format, 'ejs'].join('.'));

  fs.readFile(filename, (err, file) => {
    if (err) {
      return reject(err);
    }

    let view = _.template(file);

    // If we are in production mode, fill the view cache.
    if (process.env.NODE_ENV === 'production') {
      if (!(name in templates.data)) {
        templates.data[name] = {};
      }

      templates.data[name][format] = view;
    }

    return resolve(view(context));
  });
}); // ends templates.render

const options = {
  host: SMTP_HOST,
  auth: {
    user: SMTP_USERNAME,
    pass: SMTP_PASSWORD
  }
};

if (SMTP_PORT) {
  options.port = SMTP_PORT;
} else {
  options.port = 25;
}

const defaultTransporter = nodemailer.createTransport(options);

const mailer = module.exports = {

  /**
   * Create the new Task kue.
   */
  task: new kue.Task({
    name: 'mailer'
  }),

  sendSimple({template, locals, to, subject}) {

    if (!to) {
      return Promise.reject('sendSimple requires a comma-separated list of "to" addresses');
    }

    if (!subject) {
      return Promise.reject('sendSimple requires a subject for the email');
    }

    // Prefix the subject with `[Talk]`.
    subject = `[Talk] ${subject}`;

    locals['t'] = i18n.t;

    return Promise.all([

      // Render the HTML version of the email.
      templates.render(template, 'html', locals),

      // Render the TEXT version of the email.
      templates.render(template, 'txt', locals)
    ])
    .then(([html, text]) => {

      // Create the job.
      return mailer.task.create({
        title: 'Mail',
        message: {
          to,
          subject,
          text,
          html
        }
      });
    });
  },

  /**
   * Start the queue processor for the mailer job.
   */
  process() {

    debug(`Now processing ${mailer.task.name} jobs`);

    return mailer.task.process(({id, data}, done) => {
      debug(`Starting to send mail for Job[${id}]`);

      // Set the `from` field.
      data.message.from = SMTP_FROM_ADDRESS;

      // Actually send the email.
      defaultTransporter.sendMail(data.message, (err) => {
        if (err) {
          debug(`Failed to send mail for Job[${id}]:`, err);
          return done(err);
        }

        debug(`Finished sending mail for Job[${id}]`);
        return done();
      });
    });
  }

};
