import { wrapApiHandlerWithSentry, captureException } from "@sentry/nextjs";
import { Prisma } from "@prisma/client";
import { z, ZodError } from "zod";
import { E as ErrorWithCode, a as ErrorCode } from "./errors-SirEabuV.js";
import { TRPCError } from "@trpc/server";
import { getHTTPStatusCodeFromError } from "@trpc/server/http";
import { H as HttpError } from "./http-error-RJXCPZV2.js";
import { l as logger, an as IS_PRODUCTION } from "./orgDomains-eTg-cjth.js";
import "./perfObserver-y9pC1HYV.js";
import { performance } from "perf_hooks";
const errorSchema = z.object({
  name: z.string(),
  message: z.string(),
  stack: z.string().optional()
});
const stripeInvalidRequestErrorSchema = errorSchema.extend({
  type: z.literal("StripeInvalidRequestError"),
  rawType: z.literal("invalid_request_error"),
  code: z.string().optional(),
  doc_url: z.string().optional(),
  statusCode: z.number().optional(),
  raw: z.unknown(),
  headers: z.record(z.string()),
  requestId: z.string(),
  param: z.string().optional()
});
const log = logger.getSubLogger({ prefix: [`[redactError]`] });
function shouldRedact(error) {
  return error instanceof Prisma.PrismaClientInitializationError || error instanceof Prisma.PrismaClientKnownRequestError || error instanceof Prisma.PrismaClientUnknownRequestError || error instanceof Prisma.PrismaClientValidationError;
}
const redactError = (error) => {
  if (!(error instanceof Error)) {
    return error;
  }
  log.debug("Type of Error: ", error.constructor);
  if (shouldRedact(error) && IS_PRODUCTION) {
    log.error("Error: ", JSON.stringify(error));
    return new Error("An error occurred while querying the database.");
  }
  return error;
};
function hasName(cause) {
  return !!cause && typeof cause === "object" && "name" in cause;
}
function isZodError(cause) {
  return cause instanceof ZodError || hasName(cause) && cause.name === "ZodError";
}
function isPrismaError(cause) {
  return cause instanceof Prisma.PrismaClientKnownRequestError;
}
function parseZodErrorIssues(issues) {
  return issues.map(
    (i) => i.code === "invalid_union" ? i.unionErrors.map((ue) => parseZodErrorIssues(ue.issues)).join("; ") : i.code === "unrecognized_keys" ? i.message : `${i.path.length ? `${i.code} in '${i.path}': ` : ""}${i.message}`
  ).join("; ");
}
function getServerErrorFromUnknown(cause) {
  if (cause instanceof TRPCError) {
    const statusCode = getHTTPStatusCodeFromError(cause);
    return new HttpError({ statusCode, message: cause.message });
  }
  if (isZodError(cause)) {
    return new HttpError({
      statusCode: 400,
      message: parseZodErrorIssues(cause.issues),
      cause
    });
  }
  if (cause instanceof SyntaxError) {
    return new HttpError({
      statusCode: 500,
      message: "Unexpected error, please reach out for our customer support."
    });
  }
  if (isPrismaError(cause)) {
    return getServerErrorFromPrismaError(cause);
  }
  const parsedStripeError = stripeInvalidRequestErrorSchema.safeParse(cause);
  if (parsedStripeError.success) {
    return getHttpError({ statusCode: 400, cause: parsedStripeError.data });
  }
  if (cause instanceof ErrorWithCode) {
    const statusCode = getStatusCode(cause);
    return new HttpError({
      statusCode,
      message: cause.message ?? "",
      data: cause.data,
      cause
    });
  }
  if (cause instanceof HttpError) {
    const redactedCause = redactError(cause);
    return {
      ...redactedCause,
      name: cause.name,
      message: cause.message ?? "",
      cause: cause.cause,
      url: cause.url,
      statusCode: cause.statusCode,
      method: cause.method
    };
  }
  if (cause instanceof Error) {
    const statusCode = getStatusCode(cause);
    return getHttpError({ statusCode, cause });
  }
  if (typeof cause === "string") {
    return new Error(cause, { cause });
  }
  return new HttpError({
    statusCode: 500,
    message: `Unhandled error of type '${typeof cause}'. Please reach out for our customer support.`
  });
}
function getStatusCode(cause) {
  const errorCode = cause instanceof ErrorWithCode ? cause.code : cause.message;
  switch (errorCode) {
    case ErrorCode.RequestBodyWithouEnd:
    case ErrorCode.MissingPaymentCredential:
    case ErrorCode.MissingPaymentAppId:
    case ErrorCode.AvailabilityNotFoundInSchedule:
    case ErrorCode.CancelledBookingsCannotBeRescheduled:
    case ErrorCode.BookingTimeOutOfBounds:
    case ErrorCode.BookingNotAllowedByRestrictionSchedule:
    case ErrorCode.BookerLimitExceeded:
    case ErrorCode.BookerLimitExceededReschedule:
    case ErrorCode.EventTypeNoHosts:
    case ErrorCode.RequestBodyInvalid:
    case ErrorCode.ChargeCardFailure:
      return 400;
    case ErrorCode.NoAvailableUsersFound:
    case ErrorCode.FixedHostsUnavailableForBooking:
    case ErrorCode.RoundRobinHostsUnavailableForBooking:
    case ErrorCode.AlreadySignedUpForBooking:
    case ErrorCode.BookingSeatsFull:
    case ErrorCode.NotEnoughAvailableSeats:
    case ErrorCode.BookingConflict:
    case ErrorCode.PaymentCreationFailure:
      return 409;
    case ErrorCode.EventTypeNotFound:
    case ErrorCode.BookingNotFound:
    case ErrorCode.RestrictionScheduleNotFound:
      return 404;
    case ErrorCode.UnableToSubscribeToThePlatform:
    case ErrorCode.UpdatingOauthClientError:
    case ErrorCode.CreatingOauthClientError:
    default:
      return 500;
  }
}
function getHttpError({ statusCode, cause }) {
  const redacted = redactError(cause);
  return new HttpError({ statusCode, message: redacted.message, cause: redacted });
}
function getServerErrorFromPrismaError(cause) {
  if (cause.code === "P2025") {
    return getHttpError({ statusCode: 404, cause });
  }
  return getHttpError({ statusCode: 400, cause });
}
function defaultResponder(f, endpointRoute) {
  return async (req, res) => {
    let ok = false;
    try {
      performance.mark("Start");
      const result = endpointRoute ? await wrapApiHandlerWithSentry(f, endpointRoute)(req, res) : await f(req, res);
      ok = true;
      if (result && !res.writableEnded) {
        return res.json(result);
      }
    } catch (err) {
      const error = getServerErrorFromUnknown(err);
      if (!(error.statusCode >= 400 && error.statusCode < 500)) {
        console.error(error);
        captureException(error);
      }
      return res.status(error.statusCode).json({ message: error.message, url: error.url, method: error.method, data: error?.data || null });
    } finally {
      performance.mark("End");
      performance.measure(`[${ok ? "OK" : "ERROR"}][$1] ${req.method} '${req.url}'`, "Start", "End");
    }
  };
}
export {
  defaultResponder as d
};
