const { Auditoria } = require('../models');

// Middleware para registrar auditoría
const registrarAuditoria = (accion, tabla) => {
  return async (req, res, next) => {
    // Guardar el método original de res.json
    const originalJson = res.json.bind(res);

    // Sobrescribir res.json para capturar la respuesta
    res.json = function (data) {
      // Solo registrar si la operación fue exitosa
      if (data.success) {
        // Registrar auditoría de forma asíncrona (no bloquear la respuesta)
        setImmediate(async () => {
          try {
            const usuarioId = req.user ? req.user.id : null;
            const usuarioTipo = req.user ? req.user.type : 'anonymous';
            
            let resumen = `${accion} en ${tabla}`;
            let registroId = null;

            // Intentar obtener el ID del registro afectado
            if (data.data && data.data.Id) {
              registroId = data.data.Id;
            } else if (req.params.id) {
              registroId = req.params.id;
            }

            // Construir resumen más detallado
            if (registroId) {
              resumen += ` - ID: ${registroId}`;
            }

            // Crear registro de auditoría
            await Auditoria.create({
              UsuarioId: usuarioId,
              UsuarioTipo: usuarioTipo,
              Accion: accion,
              Tabla: tabla,
              RegistroId: registroId,
              Resumen: resumen,
              DatosAnteriores: req.body ? JSON.stringify(req.oldData || {}) : null,
              DatosNuevos: req.body ? JSON.stringify(req.body) : null,
              IP: req.ip || req.connection.remoteAddress,
              UserAgent: req.get('user-agent'),
              Interaccion: new Date()
            });
          } catch (error) {
            console.error('Error al registrar auditoría:', error);
            // No lanzar error para no afectar la respuesta al cliente
          }
        });
      }

      // Llamar al método original
      return originalJson(data);
    };

    next();
  };
};

// Middleware para capturar datos anteriores en actualizaciones
const capturarDatosAnteriores = (Model) => {
  return async (req, res, next) => {
    try {
      if (req.params.id) {
        const record = await Model.findByPk(req.params.id);
        if (record) {
          req.oldData = record.toJSON();
        }
      }
    } catch (error) {
      console.error('Error al capturar datos anteriores:', error);
    }
    next();
  };
};

module.exports = {
  registrarAuditoria,
  capturarDatosAnteriores
};