import { AxiosError } from 'axios';
import type { ErrorRequestHandler } from 'express';
import { ZodError } from 'zod';
import { logger } from '../config/logger';
import { AppError } from '../utils/AppError';

export const errorMiddleware: ErrorRequestHandler = (error, _req, res, _next) => {
  if (error instanceof AppError) {
    logger.warn({ code: error.code, details: error.details }, error.message);
    res.status(error.statusCode).json({
      error: {
        code: error.code,
        message: error.message,
        details: error.details,
      },
    });
    return;
  }

  if (error instanceof ZodError) {
    logger.warn({ issues: error.issues }, 'Validation failed');
    res.status(400).json({
      error: {
        code: 'VALIDATION_ERROR',
        message: 'Invalid request payload.',
        details: error.issues,
      },
    });
    return;
  }

  if (error instanceof AxiosError) {
    const status = error.response?.status ?? 503;
    logger.error(
      {
        status,
        code: error.code,
        url: error.config?.url,
        method: error.config?.method,
        response: error.response?.data,
      },
      'HTTP dependency failed',
    );
    res.status(status === 401 ? 502 : 503).json({
      error: {
        code: status === 401 ? 'UPSTREAM_AUTH_FAILED' : 'UPSTREAM_UNAVAILABLE',
        message: 'A dependency request failed.',
        details: error.response?.data ?? error.message,
      },
    });
    return;
  }

  logger.error({ error }, 'Unhandled error');
  res.status(500).json({
    error: {
      code: 'INTERNAL_ERROR',
      message: 'Unexpected internal error.',
    },
  });
};
