import { Request, Response, NextFunction } from 'express';
import crypto from 'crypto';
import { ILogger } from '../../application/ports/logger';

const WRITE_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);

export const auditLoggerMiddleware = (logger: ILogger) => {
  return (req: Request, res: Response, next: NextFunction): void => {
    if (!WRITE_METHODS.has(req.method)) {
      next();
      return;
    }

    const startAt = Date.now();
    const ip = req.ip ?? req.socket.remoteAddress ?? 'unknown';
    const ipHash = crypto.createHash('sha256').update(ip).digest('hex');

    res.on('finish', () => {
      const durationMs = Date.now() - startAt;
      const walletId =
        res.locals.walletId ?? req.params.walletId ?? req.body?.walletId ?? null;

      logger.info('Audit log', {
        timestamp: new Date().toISOString(),
        method: req.method,
        path: req.originalUrl ?? req.path,
        ipHash,
        statusCode: res.statusCode,
        walletId,
        success: res.statusCode < 400,
        durationMs,
        requestId: res.locals.requestId ?? req.headers['x-request-id'] ?? null,
      });
    });

    next();
  };
};
