import type { ErrorRequestHandler, RequestHandler } from 'express';

type ApiError = Error & {
  status?: number;
  statusCode?: number;
  expose?: boolean;
};

function getErrorStatus(err: unknown): number {
  const candidate = typeof err === 'object' && err !== null
    ? Number((err as ApiError).statusCode || (err as ApiError).status)
    : NaN;

  return Number.isInteger(candidate) && candidate >= 400 && candidate < 600 ? candidate : 500;
}

export const notFoundHandler: RequestHandler = (req, res) => {
  res.status(404).json({ error: `Route not found: ${req.method} ${req.originalUrl}` });
};

export const apiErrorHandler: ErrorRequestHandler = (err, req, res, next) => {
  if (res.headersSent) {
    next(err);
    return;
  }

  const status = getErrorStatus(err);
  const message = status >= 500 && !(err as ApiError | undefined)?.expose
    ? 'Internal server error'
    : (err instanceof Error ? err.message : 'Request failed');

  const logPayload = {
    method: req.method,
    path: req.originalUrl,
    status,
    message: err instanceof Error ? err.message : String(err),
    stack: err instanceof Error ? err.stack : undefined,
    ip: req.ip,
  };
  console.error('[api-error]', JSON.stringify(logPayload));

  res.status(status).json({ error: message });
};
