import { errorHandlerService } from "@batch-cooking/error-tools";
import type { NextFunction, Request, Response } from "express";
import { logger } from "../lib/logger.service.js";

/**
 * Logs every error that reaches Express's error-handling chain, then
 * passes it straight on (`next(err)`) to the real error-to-response
 * middleware (`createErrorMiddleware`, `@batch-cooking/express-tools`) —
 * mounted immediately after this one in `app.ts`. Reuses
 * `errorHandlerService.handle()` (`@batch-cooking/error-tools`) just to
 * classify the error for logging purposes (its `status`/`body.code`) —
 * `.handle()` is pure/stateless, so calling it here and then again in
 * `createErrorMiddleware` right after is harmless, and it's the one place
 * that already knows a bare `ZodError` maps to `400 VALIDATION_ERROR`, an
 * `HttpError` maps to its own `status`/`code`, and anything else is a
 * `500`. Doesn't build the actual response itself — that's still
 * `createErrorMiddleware`'s job.
 *
 * A resulting `4xx` is routine, expected operation (a validation failure,
 * a 404, an unauthenticated request) — logged at `warn`, not `error`, so a
 * genuine `5xx` (an unhandled exception, a bug) stands out instead of
 * being buried under normal client mistakes.
 */
export function errorLogger(err: unknown, req: Request, _res: Response, next: NextFunction): void {
  const meta = { method: req.method, path: req.originalUrl };
  const { status, body } = errorHandlerService.handle(err);

  if (status >= 500) {
    logger.error(err instanceof Error ? err.message : body.message, {
      ...meta,
      status,
      code: body.code,
      stack: err instanceof Error ? err.stack : undefined,
    });
  } else {
    logger.warn(body.message, { ...meta, status, code: body.code });
  }

  next(err);
}
