import { Response, NextFunction } from 'express';
import { AuthenticatedRequest } from '../../../shared/types/index.js';
import { auditService } from '../services/audit.instance.js';
import { AuditAction } from '../entities/audit-log.entity.js'; // Asumo que existe el enum

export const auditMiddleware = (action?: string, resourceType?: string) => {
  return async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
    // Solo auditamos si hay usuario y tenant (request autenticado)
    if (!req.user) {
      return next();
    }

    const originalSend = res.send;
    let responseBody: any;

    // Intercept response to log status and body (optional)
    res.send = function (body) {
      responseBody = body;
      return originalSend.apply(res, arguments as any);
    };

    res.on('finish', () => {
      // Logic to determine action if not provided
      let derivedAction = action;
      if (!derivedAction) {
        if (req.method === 'POST') derivedAction = 'CREATE';
        else if (req.method === 'PUT' || req.method === 'PATCH') derivedAction = 'UPDATE';
        else if (req.method === 'DELETE') derivedAction = 'DELETE';
        else derivedAction = 'READ';
      }

      // Logic to determine resourceType if not provided
      let derivedResource = resourceType;
      if (!derivedResource) {
        // Try to guess from URL: /api/v1/users -> users
        const parts = req.baseUrl.split('/');
        derivedResource = parts[parts.length - 1] || 'UNKNOWN';
      }

      // Evitar loguear READs masivos si no es necesario (opcional, por ahora logueamos todo lo que pase por este middleware)
      // Si el middleware se usa globalmente, filtrar GETs.
      // Si se usa por ruta, asumimos que queremos auditar.

      // Solo loguear operaciones exitosas o errores críticos?
      // Logueamos todo.

      if (res.statusCode >= 400) {
          // Podríamos loguear fallos con otra acción o flag
      }

      try {
        auditService.createAuditLog(req.user!.tenantId, {
          userId: req.user!.userId,
          action: derivedAction as any, // Cast to specific enum if needed
          resourceType: derivedResource,
          resourceId: req.params.id, // Common pattern
          ipAddress: req.ip,
          userAgent: req.get('User-Agent'),
          oldValues: undefined, // Dificil de obtener automaticamente sin hacer query previo
          newValues: req.method !== 'GET' ? req.body : undefined,
          metadata: {
            method: req.method,
            url: req.originalUrl,
            statusCode: res.statusCode
          }
        }).catch(err => console.error('Audit log error', err));
      } catch (err) {
        console.error('Audit middleware error', err);
      }
    });

    next();
  };
};
