// src/certificates/bulk-scan/multer-exception.filter.ts
import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpStatus,
  Logger,
} from '@nestjs/common';
import type { Response } from 'express';

/**
 * Translates Multer's cryptic error messages into human-readable JSON.
 *
 * Multer error codes & their real meaning:
 *   LIMIT_UNEXPECTED_FILE   → "you sent more files than maxCount, OR field name doesn't match"
 *   LIMIT_FILE_SIZE         → "one file exceeded fileSize limit"
 *   LIMIT_FILE_COUNT        → "too many files for this request"
 *   LIMIT_FIELD_COUNT       → "too many form fields"
 *   LIMIT_PART_COUNT        → "too many multipart parts"
 *   LIMIT_FIELD_KEY         → "field name too long"
 *   LIMIT_FIELD_VALUE       → "field value too long"
 *
 * Without this filter, the frontend gets things like
 * `{"message":"Unexpected field - files","statusCode":400}`
 * and has no idea what to tell the user.
 */
@Catch()
export class MulterExceptionFilter implements ExceptionFilter {
  private readonly logger = new Logger(MulterExceptionFilter.name);

  catch(exception: any, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();

    // Only handle MulterError. Everything else gets re-thrown for the
    // default Nest exception handler to deal with.
    const isMulter =
      exception?.name === 'MulterError' ||
      exception?.code?.startsWith?.('LIMIT_');

    if (!isMulter) {
      // Pass through — let Nest handle it normally.
      // We re-throw so other filters / global filter can pick it up.
      throw exception;
    }

    const code: string = exception.code || 'UNKNOWN';
    const field: string = exception.field || 'files';

    let status = HttpStatus.BAD_REQUEST;
    let message = 'File upload error';
    let hint = '';

    switch (code) {
      case 'LIMIT_UNEXPECTED_FILE':
        message = 'Too many files in one upload';
        hint =
          `You sent more files than the server accepts in a single request. ` +
          `Try uploading in smaller batches (≤ 200 files at a time), ` +
          `or make sure the form field name is "${field}".`;
        status = HttpStatus.BAD_REQUEST;
        break;

      case 'LIMIT_FILE_SIZE':
        message = 'A file is too large';
        hint = `Each file must be 25 MB or smaller. The file "${field}" exceeded this.`;
        status = HttpStatus.PAYLOAD_TOO_LARGE;
        break;

      case 'LIMIT_FILE_COUNT':
        message = 'Too many files';
        hint = 'Maximum 200 files per request. Split into smaller batches.';
        status = HttpStatus.BAD_REQUEST;
        break;

      case 'LIMIT_FIELD_COUNT':
      case 'LIMIT_PART_COUNT':
        message = 'Too many form parts in the request';
        hint = 'Make sure your form is well-formed multipart/form-data.';
        status = HttpStatus.BAD_REQUEST;
        break;

      case 'LIMIT_FIELD_KEY':
      case 'LIMIT_FIELD_VALUE':
        message = 'Form field name or value too long';
        hint = 'Shorten the field name or value.';
        status = HttpStatus.BAD_REQUEST;
        break;

      default:
        message = `Upload error (${code})`;
        hint = exception.message || 'Unknown multer error';
    }

    this.logger.warn(
      `📤 Multer rejected upload — code=${code}, field=${field}, message="${exception.message}"`,
    );

    response.status(status).json({
      statusCode: status,
      error: HttpStatus[status],
      code,
      message,
      hint,
    });
  }
}
