import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
  Logger,
} from '@nestjs/common';
import { Request, Response } from 'express';

/**
 * 모든 예외 필터 - Docker 환경에서 로그 출력 보장
 */
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  private readonly logger = new Logger('ExceptionFilter');

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

    let status: number;
    let message: string | string[];

    if (exception instanceof HttpException) {
      status = exception.getStatus();
      const exceptionResponse = exception.getResponse();

      if (typeof exceptionResponse === 'string') {
        message = exceptionResponse;
      } else if (typeof exceptionResponse === 'object' && exceptionResponse !== null) {
        message = (exceptionResponse as any).message || exception.message;
      } else {
        message = exception.message;
      }
    } else {
      status = HttpStatus.INTERNAL_SERVER_ERROR;
      message = exception instanceof Error ? exception.message : '서버 내부 오류가 발생했습니다.';
    }

    const errorResponse = {
      success: false,
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: request.url,
      method: request.method,
      message: Array.isArray(message) ? message : [message],
    };

    // 스택 트레이스 포함
    if (exception instanceof Error) {
      (errorResponse as any).stack = exception.stack;
    }

    // ========== 상세 로깅 (stdout으로 즉시 출력) ==========
    const logMessage = [
      '',
      '╔══════════════════════════════════════════════════════════════╗',
      '║                    EXCEPTION OCCURRED                        ║',
      '╚══════════════════════════════════════════════════════════════╝',
      `  Timestamp : ${errorResponse.timestamp}`,
      `  Method    : ${request.method}`,
      `  Path      : ${request.url}`,
      `  Status    : ${status}`,
      `  Message   : ${JSON.stringify(message)}`,
    ];

    if (exception instanceof Error) {
      logMessage.push(`  Error Name: ${exception.name}`);
      logMessage.push(`  Stack     :`);
      logMessage.push(exception.stack || 'No stack trace');
    }

    // Request Body 로깅 (민감정보 마스킹)
    const safeBody = { ...request.body };
    if (safeBody.password) safeBody.password = '****';
    if (safeBody.token) safeBody.token = '****';
    logMessage.push(`  Body      : ${JSON.stringify(safeBody)}`);
    logMessage.push('══════════════════════════════════════════════════════════════════');
    logMessage.push('');

    // NestJS Logger 사용 (Docker stdout으로 출력)
    this.logger.error(logMessage.join('\n'));

    // 추가로 console.error도 출력 (백업)
    console.error(logMessage.join('\n'));

    // process.stdout으로 직접 출력 (버퍼링 우회)
    process.stdout.write(logMessage.join('\n') + '\n');

    response.status(status).json(errorResponse);
  }
}
