import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common';
import { status as GrpcStatus } from '@grpc/grpc-js';

interface HttpResponseLike {
  status(code: number): { json(body: unknown): unknown };
}

function grpcToHttp(code?: number): number {
  switch (code) {
    case GrpcStatus.INVALID_ARGUMENT:
    case GrpcStatus.FAILED_PRECONDITION:
    case GrpcStatus.OUT_OF_RANGE:
      return 400;
    case GrpcStatus.UNAUTHENTICATED:
      return 401;
    case GrpcStatus.PERMISSION_DENIED:
      return 403;
    case GrpcStatus.NOT_FOUND:
      return 404;
    case GrpcStatus.ALREADY_EXISTS:
      return 409;
    case GrpcStatus.RESOURCE_EXHAUSTED:
      return 429;
    default:
      return 500;
  }
}

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost): void {
    const response = host.switchToHttp().getResponse<HttpResponseLike>();

    if (exception instanceof HttpException) {
      const statusCode = exception.getStatus();
      const payload = exception.getResponse();
      response.status(statusCode).json(typeof payload === 'string' ? { statusCode, message: payload } : payload);
      return;
    }

    const grpcError = exception as { code?: number; details?: string; message?: string };
    const statusCode = grpcToHttp(grpcError?.code);
    const message = grpcError?.details || grpcError?.message || 'Ошибка сервиса';
    response.status(statusCode).json({ statusCode, message });
  }
}
