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

'use strict';

const path = require('path');

const mongoose = require('mongoose');

const ContentReport = mongoose.model('ContentReport');

const pug = require('pug');
const striptags = require('striptags');

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

class ContentReportService extends SiteService {

  constructor (dtp) {
    super(dtp, module.exports);
    this.populateContentReport = [
      {
        path: 'user',
        select: '_id username username_lc displayName picture',
      },
      {
        path: 'resource',
        populate: [
          {
            path: 'author',
            select: '_id username username_lc displayName picture',
          },
        ],
      },
    ];
  }

  async start ( ) {
    await super.start();

    this.templates = { };
    this.templates.comment = pug.compileFile(path.join(this.dtp.config.root, 'app', 'views', 'comment', 'components', 'comment-standalone.pug'));
  }

  async create (user, reportDefinition) {
    const NOW = new Date();
    const report = new ContentReport();

    report.created = NOW;
    report.user = user._id;
    report.resourceType = reportDefinition.resourceType;
    report.resource = reportDefinition.resourceId;
    report.status = 'new';
    report.category = reportDefinition.category;
    report.reason = striptags(reportDefinition.reason.trim());

    await report.save();

    return report.toObject();
  }

  async getReports (status, pagination) {
    if (!Array.isArray(status)) {
      status = [status];
    }
    const reports = await ContentReport
      .find({ status: { $in: status } })
      .sort({ created: 1 })
      .skip(pagination.skip)
      .limit(pagination.cpp)
      .populate(this.populateContentReport)
      .lean();
    return reports;
  }

  async getById (reportId) {
    const report = await ContentReport
      .findById(reportId)
      .populate(this.populateContentReport)
      .lean();
    return report;
  }

  async setStatus (report, status) {
    await ContentReport.updateOne({ _id: report._id }, { $set: { status } });
  }

  async removeResource (report) {
    switch (report.resourceType) {
      case 'Comment':
        return this.removeComment(report);
      case 'Chat':
        return this.removeChatMessage(report);
      default:
        break;
    }
    this.log.error('invalid resource type in content report', {
      reportId: report._id,
      resourceType: report.resourceType,
    });
    throw new SiteError(406, 'Invalid resource type in content report');
  }

  async removeComment (report) {
    const { comment: commentService } = this.dtp.services;
    await commentService.remove(report.resource._id || report.resource, 'mod-removed');
    await this.setStatus(report, 'resolved');
  }

  async removeChatMessage (report) {
    const { chat: chatService } = this.dtp.services;
    await chatService.removeMessage(report.resource);
  }

  async removeForResource (resource) {
    await ContentReport.deleteMany({ resource: resource._id });
  }

  async removeReport (report) {
    await ContentReport.deleteOne({ _id: report._id });
  }
}

module.exports = {
  slug: 'content-report',
  name: 'contentReport',
  create: (dtp) => { return new ContentReportService(dtp); },
};