"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const indexBrowser = require("./index-browser-RtwB1hqI.cjs");
const errors = require("./errors-CzUssrMn.cjs");
const index = require("./index-QSf6WJj0.cjs");
const getCalEventResponses = require("./getCalEventResponses-5xtsj5PI.cjs");
const addVideoCallDataToEvent = require("./addVideoCallDataToEvent-Rhi83lB7.cjs");
const z = require("zod");
const buildCalendarEvent = async (bookingUid) => {
  const booking = await index.prisma.booking.findUnique({
    where: {
      uid: bookingUid
    },
    include: {
      user: {
        select: {
          name: true,
          email: true,
          locale: true,
          username: true,
          timeZone: true,
          timeFormat: true
        }
      },
      eventType: {
        select: {
          slug: true,
          bookingFields: true
        }
      },
      attendees: {
        select: {
          email: true,
          locale: true,
          name: true,
          timeZone: true,
          phoneNumber: true
        }
      },
      references: true
    }
  });
  if (!booking) {
    throw new Error(`booking not found for bookings: ${bookingUid}`);
  }
  if (!booking.user) {
    throw new Error(`organizer not found for booking: ${bookingUid}`);
  }
  if (!booking.eventType) {
    throw new Error(`event type not found for booking ${bookingUid}`);
  }
  const organizerT = await indexBrowser.getTranslation(booking.user?.locale ?? "en", "common");
  const attendeePromises = [];
  for (const attendee of booking.attendees) {
    attendeePromises.push(
      indexBrowser.getTranslation(attendee.locale ?? "en", "common").then((tAttendee) => ({
        email: attendee.email,
        name: attendee.name,
        timeZone: attendee.timeZone,
        language: { translate: tAttendee, locale: attendee.locale ?? "en" },
        phoneNumber: attendee.phoneNumber || void 0
      }))
    );
  }
  const attendeeList = await Promise.all(attendeePromises);
  let calendarEvent = {
    uid: bookingUid,
    type: booking.eventType.slug,
    title: booking.title,
    startTime: booking.startTime.toISOString(),
    endTime: booking.endTime.toISOString(),
    organizer: {
      email: booking.user.email,
      name: booking.user.name || "Nameless",
      username: booking.user?.username || "No username",
      language: { translate: organizerT, locale: booking.user?.locale ?? "en" },
      timeZone: booking.user.timeZone
    },
    attendees: attendeeList,
    location: booking.location,
    ...getCalEventResponses.getCalEventResponses({
      bookingFields: booking?.eventType?.bookingFields ?? null,
      booking
    })
  };
  calendarEvent = addVideoCallDataToEvent.addVideoCallDataToEvent(booking.references, calendarEvent);
  return calendarEvent;
};
const buildCalendarEvent$1 = buildCalendarEvent;
const createCRMEventSchema = z.object({
  bookingUid: z.string()
});
const log = index.logger.getSubLogger({ prefix: [`[[tasker] createCRMEvent`] });
const handleErrors = ({
  errorPerApp,
  payload
}) => {
  const errorMsgs = Object.entries(errorPerApp).map(([appSlug, error]) => {
    if (error instanceof Error) {
      return `(app: ${appSlug}) ${error.message}`;
    }
    return `(app: ${appSlug}) ${error}`;
  });
  if (errorMsgs.length > 0) {
    const hasAnyRetryableErrors = Object.values(errorPerApp).some((error) => error instanceof errors.RetryableError);
    if (hasAnyRetryableErrors) {
      throw new Error(errorMsgs.join("\n"));
    }
    log.error(`[Will not retry] Error creating CRM event for payload ${payload}: ${errorMsgs.join("\n")}`);
  }
};
async function createCRMEvent(payload) {
  try {
    const parsedPayload = createCRMEventSchema.safeParse(JSON.parse(payload));
    if (!parsedPayload.success) {
      throw new Error(`malformed payload in createCRMEvent: ${parsedPayload.error}`);
    }
    const { bookingUid } = parsedPayload.data;
    const booking = await index.prisma.booking.findUnique({
      where: {
        uid: bookingUid
      },
      include: {
        user: {
          select: {
            name: true,
            email: true,
            locale: true,
            username: true,
            timeZone: true
          }
        },
        eventType: {
          select: {
            metadata: true
          }
        },
        references: {
          select: {
            type: true
          }
        }
      }
    });
    if (!booking) {
      throw new Error(`booking not found for uid: ${bookingUid}`);
    }
    if (booking.status !== index.BookingStatus.ACCEPTED) {
      log.info(`Booking status is not ACCEPTED`);
      return;
    }
    if (!booking.user) {
      throw new Error(`user not found for uid: ${bookingUid}`);
    }
    const eventTypeMetadata = indexBrowser.EventTypeMetaDataSchema.safeParse(booking.eventType?.metadata);
    if (!eventTypeMetadata.success) {
      throw new Error(`malformed event type metadata: ${eventTypeMetadata.error}`);
    }
    const eventTypeAppMetadata = eventTypeMetadata.data?.apps;
    if (!eventTypeAppMetadata) {
      throw new Error(`event type app metadata not found for booking ${bookingUid}`);
    }
    const calendarEvent = await buildCalendarEvent$1(bookingUid);
    const bookingReferencesToCreate = [];
    const existingBookingReferences = await index.prisma.bookingReference.findMany({
      where: {
        bookingId: booking.id
      }
    });
    const errorPerApp = {};
    for (const appSlug of Object.keys(eventTypeAppMetadata)) {
      try {
        const appData = eventTypeAppMetadata[appSlug];
        const appDataSchema = indexBrowser.appDataSchemas[appSlug];
        if (!appData || !appDataSchema) {
          throw new Error(`Could not find appData or appDataSchema for ${appSlug}`);
        }
        const appParse = appDataSchema.safeParse(appData);
        if (!appParse.success) {
          log.error(`Error parsing event type app data for bookingUid ${bookingUid}`, appParse?.error);
          continue;
        }
        const app = appParse.data;
        const hasCrmCategory = app.appCategories && app.appCategories.some((category) => category === "crm");
        if (!app.enabled || !app.credentialId || !hasCrmCategory) {
          log.info(`Skipping CRM app ${appSlug}`, {
            enabled: app.enabled,
            credentialId: app.credentialId,
            hasCrmCategory
          });
          continue;
        }
        const crmCredential = await index.prisma.credential.findUnique({
          where: {
            id: app.credentialId
          },
          include: {
            user: {
              select: {
                email: true
              }
            }
          }
        });
        if (!crmCredential) {
          throw new Error(`Credential not found for credentialId: ${app.credentialId}`);
        }
        const existingBookingReferenceForTheCredential = existingBookingReferences.find(
          (reference) => reference.credentialId === crmCredential.id
        );
        if (existingBookingReferenceForTheCredential) {
          log.info(`Skipping CRM app ${appSlug} as booking reference already exists`, {
            credentialId: crmCredential.id,
            bookingReferenceId: existingBookingReferenceForTheCredential.id
          });
          continue;
        }
        const CrmManager = (await Promise.resolve().then(() => require("./crmManager-ZPS3ci3E.cjs"))).default;
        const crm = new CrmManager(crmCredential, app);
        const results = await crm.createEvent(calendarEvent);
        if (results) {
          bookingReferencesToCreate.push({
            type: crmCredential.type,
            uid: results.id,
            meetingId: results.id,
            credentialId: crmCredential.id,
            bookingId: booking.id
          });
        }
      } catch (error) {
        errorPerApp[appSlug] = error;
      }
    }
    await index.prisma.bookingReference.createMany({
      data: bookingReferencesToCreate
    });
    handleErrors({ errorPerApp, payload });
  } catch (error) {
    const errorMsg = `Error creating crm event: error: ${indexBrowser.safeStringify(error)} Data: ${indexBrowser.safeStringify({
      payload
    })}`;
    log.error(`[Will retry] ${errorMsg}`);
    throw error;
  }
}
exports.createCRMEvent = createCRMEvent;
