"use strict";
const Sentry = require("@sentry/nextjs");
const client = require("@prisma/client");
const z = require("zod");
const errors = require("./errors-fb9bpDY1.cjs");
const server = require("@trpc/server");
const http = require("@trpc/server/http");
const httpError = require("./http-error-mkY8Ke7V.cjs");
const index = require("./index-QSf6WJj0.cjs");
require("./perfObserver-cOOJ929u.cjs");
const perf_hooks = require("perf_hooks");
const errorSchema = z.z.object({
  name: z.z.string(),
  message: z.z.string(),
  stack: z.z.string().optional()
});
const stripeInvalidRequestErrorSchema = errorSchema.extend({
  type: z.z.literal("StripeInvalidRequestError"),
  rawType: z.z.literal("invalid_request_error"),
  code: z.z.string().optional(),
  doc_url: z.z.string().optional(),
  statusCode: z.z.number().optional(),
  raw: z.z.unknown(),
  headers: z.z.record(z.z.string()),
  requestId: z.z.string(),
  param: z.z.string().optional()
});
const log = index.logger.getSubLogger({ prefix: [`[redactError]`] });
function shouldRedact(error) {
  return error instanceof client.Prisma.PrismaClientInitializationError || error instanceof client.Prisma.PrismaClientKnownRequestError || error instanceof client.Prisma.PrismaClientUnknownRequestError || error instanceof client.Prisma.PrismaClientValidationError;
}
const redactError = (error) => {
  if (!(error instanceof Error)) {
    return error;
  }
  log.debug("Type of Error: ", error.constructor);
  if (shouldRedact(error) && index.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 z.ZodError || hasName(cause) && cause.name === "ZodError";
}
function isPrismaError(cause) {
  return cause instanceof client.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 server.TRPCError) {
    const statusCode = http.getHTTPStatusCodeFromError(cause);
    return new httpError.HttpError({ statusCode, message: cause.message });
  }
  if (isZodError(cause)) {
    return new httpError.HttpError({
      statusCode: 400,
      message: parseZodErrorIssues(cause.issues),
      cause
    });
  }
  if (cause instanceof SyntaxError) {
    return new httpError.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 errors.ErrorWithCode) {
    const statusCode = getStatusCode(cause);
    return new httpError.HttpError({
      statusCode,
      message: cause.message ?? "",
      data: cause.data,
      cause
    });
  }
  if (cause instanceof httpError.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.HttpError({
    statusCode: 500,
    message: `Unhandled error of type '${typeof cause}'. Please reach out for our customer support.`
  });
}
function getStatusCode(cause) {
  const errorCode = cause instanceof errors.ErrorWithCode ? cause.code : cause.message;
  switch (errorCode) {
    case errors.ErrorCode.RequestBodyWithouEnd:
    case errors.ErrorCode.MissingPaymentCredential:
    case errors.ErrorCode.MissingPaymentAppId:
    case errors.ErrorCode.AvailabilityNotFoundInSchedule:
    case errors.ErrorCode.CancelledBookingsCannotBeRescheduled:
    case errors.ErrorCode.BookingTimeOutOfBounds:
    case errors.ErrorCode.BookingNotAllowedByRestrictionSchedule:
    case errors.ErrorCode.BookerLimitExceeded:
    case errors.ErrorCode.BookerLimitExceededReschedule:
    case errors.ErrorCode.EventTypeNoHosts:
    case errors.ErrorCode.RequestBodyInvalid:
    case errors.ErrorCode.ChargeCardFailure:
      return 400;
    case errors.ErrorCode.NoAvailableUsersFound:
    case errors.ErrorCode.FixedHostsUnavailableForBooking:
    case errors.ErrorCode.RoundRobinHostsUnavailableForBooking:
    case errors.ErrorCode.AlreadySignedUpForBooking:
    case errors.ErrorCode.BookingSeatsFull:
    case errors.ErrorCode.NotEnoughAvailableSeats:
    case errors.ErrorCode.BookingConflict:
    case errors.ErrorCode.PaymentCreationFailure:
      return 409;
    case errors.ErrorCode.EventTypeNotFound:
    case errors.ErrorCode.BookingNotFound:
    case errors.ErrorCode.RestrictionScheduleNotFound:
      return 404;
    case errors.ErrorCode.UnableToSubscribeToThePlatform:
    case errors.ErrorCode.UpdatingOauthClientError:
    case errors.ErrorCode.CreatingOauthClientError:
    default:
      return 500;
  }
}
function getHttpError({ statusCode, cause }) {
  const redacted = redactError(cause);
  return new httpError.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 {
      perf_hooks.performance.mark("Start");
      const result = endpointRoute ? await Sentry.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);
        Sentry.captureException(error);
      }
      return res.status(error.statusCode).json({ message: error.message, url: error.url, method: error.method, data: error?.data || null });
    } finally {
      perf_hooks.performance.mark("End");
      perf_hooks.performance.measure(`[${ok ? "OK" : "ERROR"}][$1] ${req.method} '${req.url}'`, "Start", "End");
    }
  };
}
exports.defaultResponder = defaultResponder;
