// newsletter.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0

'use strict';

const striptags = require('striptags');

const { SiteService } = require('../../lib/site-lib');

const mongoose = require('mongoose');

const Newsletter = mongoose.model('Newsletter');
const NewsletterRecipient = mongoose.model('NewsletterRecipient');

class NewsletterService extends SiteService {

  constructor (dtp) {
    super(dtp, module.exports);

    this.populateNewsletter = [
      {
        path: 'author',
        select: '_id username username_lc displayName picture',
      },
    ];
  }

  async create (author, newsletterDefinition) {
    const NOW = new Date();

    const newsletter = new Newsletter();
    newsletter.created = NOW;
    newsletter.author = author._id;
    newsletter.title = striptags(newsletterDefinition.title.trim());
    newsletter.summary = striptags(newsletterDefinition.summary.trim());
    newsletter.content.html = newsletterDefinition['content.html'].trim();
    newsletter.content.text = striptags(newsletterDefinition['content.text'].trim());
    newsletter.status = 'draft';

    await newsletter.save();

    return newsletter.toObject();
  }

  async update (newsletter, newsletterDefinition) {
    const updateOp = { $set: { } };

    if (newsletterDefinition.title) {
      updateOp.$set.title = striptags(newsletterDefinition.title.trim());
    }
    if (newsletterDefinition.summary) {
      updateOp.$set.summary = striptags(newsletterDefinition.summary.trim());
    }
    if (newsletterDefinition['content.html']) {
      updateOp.$set['content.html'] = newsletterDefinition['content.html'].trim();
    }
    if (newsletterDefinition['content.text']) {
      updateOp.$set['content.text'] = striptags(newsletterDefinition['content.text'].trim());
    }
    if (newsletterDefinition.status) {
      updateOp.$set.status = striptags(newsletterDefinition.status.trim());
    }

    if (Object.keys(updateOp.$set).length === 0) {
      return; // no update to perform
    }

    await Newsletter.updateOne(
      { _id: newsletter._id },
      updateOp,
      { upsert: true },
    );
  }

  async getNewsletters (pagination, status = ['published']) {
    if (!Array.isArray(status)) {
      status = [status];
    }
    const newsletters = await Newsletter
      .find({ status: { $in: status } })
      .sort({ created: -1 })
      .skip(pagination.skip)
      .limit(pagination.cpp)
      .lean();
    return newsletters;
  }

  async getById (newsletterId) {
    const newsletter = await Newsletter
      .findById(newsletterId)
      .select('+content.html +content.text')
      .populate(this.populateNewsletter)
      .lean();
    return newsletter;
  }

  async addRecipient (emailAddress) {
    const { email: emailService } = this.dtp.services;
    const NOW = new Date();

    await emailService.checkEmailAddress(emailAddress);

    const recipient = new NewsletterRecipient();
    recipient.created = NOW;
    recipient.address = striptags(emailAddress.trim());
    recipient.address_lc = recipient.address.toLowerCase();
    await recipient.save();

    return recipient.toObject();
  }

  async deleteNewsletter (newsletter) {
    this.log.info('deleting newsletter', { newsletterId: newsletter._id });
    await Newsletter.deleteOne({ _id: newsletter._id });
  }
}

module.exports = {
  slug: 'newsletter',
  name: 'newsletter',
  create: (dtp) => { return new NewsletterService(dtp); },
};
