text: const { getDb: db } = require('../mongoSetup')
  const ObjectID = require('mongodb').ObjectID
  
  module.exports = {
    addChange: (datasetId, userId, data) => {
      const { type, newItems=[], oldItems=[] } = data
      const itemIds = [ ...newItems, ...oldItems ]
        .map(item =>  item._id)
        .filter((val, i, self) => self.indexOf(val) === i)
      return db().collection("changelog")
        .insertOne({
          "type": type,
          "dataset_id": ObjectID(datasetId),
          "user_id": ObjectID(userId),
          "action_timestamp": new Date(),
          "item_ids": itemIds,
          "new_values": newItems,
          "old_values": oldItems
        })
    },
    getAudit: (datasetId) => {
      return db().collection("changelog")
        .aggregate([
          {
            $match: {
              type: { $ne: "viewlog" },
              dataset_id: ObjectID(datasetId),
              action_timestamp: { $type: "date" }
            }
          },
          {
            $group: {
              _id: {
                type: "$type",
                user: "$user_id",
                hour: { $hour: "$action_timestamp" }
              },
              type: { $first: "$type" },
              item_ids: { $push: "$item_ids" },
              new_values: { $push: "$new_values" },
              old_values: { $push: "$old_values" },
              user_id: { $first: "$user_id" },
              action_timestamp: { $first: "$action_timestamp" }
            }
          },
          {
            $addFields: {
              item_ids: {
                $reduce: {
                  input: "$item_ids",
                  initialValue: [],
                  in: {
                    "$concatArrays": [
                      "$$value",
                      "$$this"
                    ]
                  }
                }
              },
              new_values: {
                $reduce: {
                  input: "$new_values",
                  initialValue: [],
                  in: {
                    "$concatArrays": [
                      "$$value",
                      "$$this"
                    ]
                  }
                }
              },
              old_values: {
                $reduce: {
                  input: "$old_values",
                  initialValue: [],
                  in: {
                    "$concatArrays": [
                      "$$value",
                      "$$this"
                    ]
                  }
                }
              }
            }
          },
          {
            $lookup: {
              from: "users",
              localField: "user_id",
              foreignField: "_id",
              as: "user"
            }
          },
          {
            $sort: {
              action_timestamp: -1
            }
          }
        ])
        .toArray()
    },
    addViewer: (datasetId, userId) => {
      return db().collection("changelog")
        .insertOne({
          "type": "viewlog",
          "dataset_id": ObjectID(datasetId),
          "viewer_id": ObjectID(userId),
          "viewed_on": new Date()
        })
    },
    getViewlog: (datasetId) => {
      return db().collection("changelog")
        .aggregate([
          {
            $match: {
              type: "viewlog",
              dataset_id: ObjectID(datasetId),
              viewed_on: { $type: "date" }
            }
          },
          {
            $group: {
              _id: {
                viewer: "$viewer_id",
                hour: { $hour: "$viewed_on"}
              },
              type: { $first: "$type" },
              viewer_id: { $first: "$viewer_id" },
              viewed_on: { $first: "$viewed_on" }
            }
          },
          {
            $lookup: {
              from: "users",
              localField: "viewer_id",
              foreignField: "_id",
              as: "viewer"
            }
          },
          {
            $sort: {
              viewed_on: -1
            }
          }
        ]).toArray()
    }
  }