import { Request, Response, NextFunction } from 'express';
import { Error as ApiError } from '@unito/integration-api';
import { default as Logger, Metadata } from '../resources/logger.js';

declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace Express {
    interface Locals {
      logger: Logger;
      error?: ApiError;
    }
  }
}

function onFinish(req: Request, res: Response, next: NextFunction) {
  res.on('finish', function () {
    const logger = res.locals.logger ?? new Logger();
    const error = res.locals.error;

    const endMetrics = res.locals.requestMetrics.endRequest();
    const durationInNs = Number(endMetrics.durationNs);
    const durationInMs = (durationInNs / 1_000_000) | 0;

    const routePath = (req.route as { path?: string } | undefined)?.path;
    const urlCategory = typeof routePath === 'string' ? `${req.baseUrl}${routePath}` : 'unmatched';

    const message = `${req.method} ${req.originalUrl} ${res.statusCode} - ${durationInMs} ms`;
    const metadata: Metadata = {
      duration: durationInNs,
      externalApiCount: endMetrics.apiCallCount,
      externalApiTotalDuration: endMetrics.totalApiDurationNs,
      throttleDelayTotal: endMetrics.totalThrottleDelayNs,
      // Use reserved and standard attributes of Datadog
      // https://app.datadoghq.com/logs/pipelines/standard-attributes
      http: {
        method: req.method,
        status_code: res.statusCode,
        url_category: urlCategory,
        url_details: { path: req.originalUrl },
      },
      ...(error
        ? {
            error: {
              kind: error.message,
              stack: (error.originalError?.details?.stack ?? error.details?.stack) as string,
              message: error.originalError?.message ?? error.message,
            },
          }
        : {}),
    };

    if ([404, 429].includes(res.statusCode)) {
      logger.warn(message, metadata);
    } else if (res.statusCode >= 400) {
      logger.error(message, metadata);
    } else if (req.originalUrl !== '/health') {
      // Don't log successful health check requests
      logger.info(message, metadata);
    }
  });

  next();
}

export default onFinish;
