import { Router } from 'express';
import { body, query } from 'express-validator';
import AuditLog from '../models/AuditLog.js';
import { protect } from '../middlewares/auth.js';
import { authorize } from '../middlewares/authorize.js';
import { ACTIONS } from '../utils/permissions.js';
import { handleValidation } from '../utils/handleValidation.js';

const router = Router();

router.get(
  '/',
  protect,
  authorize(ACTIONS.AUDIT_VIEW),
  query('page').optional().isInt({ min: 1 }),
  query('limit').optional().isInt({ min: 1, max: 100 }),
  query('action').optional().isString().trim(),
  query('entity').optional().isString().trim(),
  query('userId').optional().isMongoId().withMessage('Invalid user id'),
  query('from').optional().isISO8601(),
  query('to').optional().isISO8601(),
  query('search').optional().isString().trim().isLength({ max: 120 }),
  handleValidation,
  async (req, res, next) => {
    try {
      const page = Math.max(1, Number(req.query.page) || 1);
      const limit = Math.min(100, Math.max(1, Number(req.query.limit) || 20));

      const filter = {};
      if (req.query.action) filter.action = String(req.query.action).trim();
      if (req.query.entity) filter.entity = String(req.query.entity).trim();
      if (req.query.userId) filter['user.id'] = req.query.userId;
      if (req.query.from || req.query.to) {
        filter.createdAt = {};
        if (req.query.from) filter.createdAt.$gte = new Date(req.query.from);
        if (req.query.to) {
          const to = new Date(req.query.to);
          to.setHours(23, 59, 59, 999);
          filter.createdAt.$lte = to;
        }
      }
      if (req.query.search) {
        const rx = new RegExp(String(req.query.search).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i');
        filter.$or = [
          { action: rx },
          { entity: rx },
          { description: rx },
          { entityId: rx },
          { 'user.name': rx },
        ];
      }

      const [logs, total] = await Promise.all([
        AuditLog.find(filter)
          .sort('-createdAt')
          .skip((page - 1) * limit)
          .limit(limit),
        AuditLog.countDocuments(filter),
      ]);
      res.json({ success: true, data: { logs, total, page, pages: Math.ceil(total / limit) } });
    } catch (error) {
      next(error);
    }
  }
);

// Distinct values for filter dropdowns
router.get('/facets', protect, authorize(ACTIONS.AUDIT_VIEW), async (_req, res, next) => {
  try {
    const [actions, entities, users] = await Promise.all([
      AuditLog.distinct('action'),
      AuditLog.distinct('entity'),
      AuditLog.aggregate([
        { $group: { _id: '$user.id', name: { $first: '$user.name' }, role: { $first: '$user.role' } } },
        { $sort: { name: 1 } },
      ]),
    ]);
    res.json({ success: true, data: { actions, entities, users } });
  } catch (error) {
    next(error);
  }
});

export default router;
