import dotenv from 'dotenv';
import { auditLogModel } from '../../database/schemas/management/auditlog.schema.js';
import log4js from 'log4js';
import mongoose from 'mongoose';
import { getModelStats, getModelHistory } from '../../database/database.js';

dotenv.config();
const logger = log4js.getLogger('AuditLogs');
logger.level = process.env.LOG_LEVEL;

export const listAuditLogsRouteHandler = async (
  req,
  res,
  page = 1,
  limit = 25,
  filter = {},
  sort = '',
  order = 'ascend'
) => {
  try {
    // Calculate the skip value based on the page number and limit
    const skip = (page - 1) * limit;
    const sortOrder = order === 'descend' ? 1 : -1;

    if (!sort || sort != '') {
      sort = 'createdAt';
    }
    // Translate parent._id to parent for Mongoose
    if (filter['parent._id']) {
      filter.parent = filter['parent._id'];
      delete filter['parent._id'];
    }

    // Translate owner._id to parent for Mongoose
    if (filter['owner._id']) {
      filter.owner = filter['owner._id'];
      delete filter['owner._id'];
    }

    console.log('sort: ', { [sort]: sortOrder });

    // Use find with population and filter
    let query = auditLogModel
      .find(filter)
      .sort({ [sort]: sortOrder })
      .skip(skip)
      .limit(Number(limit))
      .populate('owner', 'name _id');

    const auditLogs = await query;
    logger.trace(
      `List of audit logs (Page ${page}, Limit ${limit}, Sort ${sort}, Order ${order}):`,
      auditLogs
    );

    const expandedIdAuditLogs = auditLogs.map((auditLog) => {
      const expendedAuditLog = { ...auditLog._doc, parent: { _id: auditLog.parent } };
      return expendedAuditLog;
    });
    res.send(expandedIdAuditLogs);
  } catch (error) {
    logger.error('Error listing audit logs:', error);
    res.status(500).send({ error: error });
  }
};

export const getAuditLogRouteHandler = async (req, res) => {
  try {
    // Get ID from params
    const id = new mongoose.Types.ObjectId(req.params.id);
    // Fetch the audit log with the given ID
    const auditLog = await auditLogModel
      .findOne({
        _id: id,
      })
      .populate('printer')
      .populate('owner')
      .populate('parent');

    if (!auditLog) {
      logger.warn(`Audit log not found with supplied id.`);
      return res.status(404).send({ error: 'Audit log not found.' });
    }

    logger.trace(`Audit log with ID: ${id}:`, auditLog);
    res.send(auditLog);
  } catch (error) {
    logger.error('Error fetching audit log:', error);
    res.status(500).send({ error: error.message });
  }
};

export const getAuditLogStatsRouteHandler = async (req, res) => {
  const result = await getModelStats({ model: auditLogModel });
  if (result?.error) {
    logger.error('Error fetching audit log stats:', result.error);
    return res.status(result.code).send(result);
  }
  logger.trace('Audit log stats:', result);
  res.send(result);
};

export const getAuditLogHistoryRouteHandler = async (req, res) => {
  const from = req.query.from;
  const to = req.query.to;
  const result = await getModelHistory({ model: auditLogModel, from, to });
  if (result?.error) {
    logger.error('Error fetching audit log history:', result.error);
    return res.status(result.code).send(result);
  }
  logger.trace('Audit log history:', result);
  res.send(result);
};
