// Audit Logging Middleware

import { Request, Response, NextFunction } from 'express';
import { AuthenticatedRequest } from './auth.middleware';
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';

export async function auditLogMiddleware(
  req: AuthenticatedRequest,
  res: Response,
  next: NextFunction
): Promise<void> {
  const startTime = Date.now();

  // Capture response
  const originalSend = res.send;
  res.send = function (body: any) {
    const duration = Date.now() - startTime;

    // Log audit entry asynchronously (don't block response)
    logAuditEntry(req, res, duration, body).catch((err) => {
      logger.error('Failed to log audit entry', {
        error: err instanceof Error ? err.message : 'Unknown error',
        path: req.path,
        method: req.method,
      });
    });

    return originalSend.call(this, body);
  };

  next();
}

async function logAuditEntry(
  req: AuthenticatedRequest,
  res: Response,
  duration: number,
  responseBody: any
): Promise<void> {
  try {
    await prisma.auditLog.create({
      data: {
        eventType: 'api_request',
        entityType: 'api',
        entityId: req.path,
        action: `${req.method} ${req.path}`,
        actorId: req.sovereignBankId,
        actorType: req.identityType || 'unknown',
        details: {
          method: req.method,
          path: req.path,
          query: req.query,
          statusCode: res.statusCode,
          duration,
          responseSize: JSON.stringify(responseBody).length,
        },
        timestamp: new Date(),
        ipAddress: req.ip || req.headers['x-forwarded-for'] as string,
        userAgent: req.headers['user-agent'],
      },
    });
  } catch (error) {
    // Don't throw - audit logging should not break the application
    logger.error('Audit log error', {
      error: error instanceof Error ? error.message : 'Unknown error',
      path: req.path,
      method: req.method,
    });
  }
}

