import { h as appStoreMetadata, b as getAppFromSlug } from "./utils-TrPY7mDR.js";
import { g } from "./utils-TrPY7mDR.js";
import z__default, { z } from "zod";
import { g as getCalendar } from "./getCalendar-wXE4EiTO.js";
import { g as getCalEventResponses } from "./getCalEventResponses-Sb7XbRd2.js";
import { c as deleteWebhookScheduledTriggers } from "./scheduleTrigger-djVvWFC3.js";
import { D as DelegationCredentialRepository, c as checkIfSuccessfullyConfiguredInWorkspace } from "./credential-INULiwKH.js";
import { b } from "./credential-INULiwKH.js";
import { a as isPrismaObjOrUndefined } from "./isPrismaObj-NqBB0qe9.js";
import { p as parseRecurringEvent } from "./isRecurringEvent-jPe_vtM6.js";
import { D as DailyLocationType } from "./locations-K3BJPw7I.js";
import { a as appStore } from "./index-uMmDQCED.js";
import { p as prisma, c as credentialForCalendarServiceSelect, x as AppCategories, E as EventTypeMetaDataSchema, ax as eventTypeAppMetadataOptionalSchema, d as bookingMinimalSelect, B as BookingStatus, j as getTranslation, e as eventTypeMetaDataSchemaWithTypedApps, ar as userMetadata, av as serviceAccountKeySchema, l as logger, a as safeStringify } from "./orgDomains-eTg-cjth.js";
import { f as buildNonDelegationCredential, e as buildNonDelegationCredentials } from "./user-9vti0VBh.js";
import { l as sendCancelledEmailsAndSMS, P as sendDelegationCredentialDisabledEmail } from "./email-manager-mHSBIi6g.js";
import { g as getEnabledAppsFromCredentials } from "./getEnabledAppsFromCredentials-6FWyB9jb.js";
import { Prisma } from "@prisma/client";
import { TRPCError } from "@trpc/server";
import { g as getUsersCredentialsIncludeServiceAccountKey, c as checkAdminOrOwner } from "./getUsersCredentials-qqbNgwio.js";
import { M as MembershipRepository } from "./membership-ag-BKf36.js";
import { d, b as b2, C, a, e, c } from "./CalendarAppError-I94WN34B.js";
import { b as b3 } from "./universalSchema-lXT1PUH8.js";
import { I } from "./CalendarService-dEPBCVUO.js";
import { A } from "./CalendarService-P8Frl7hP.js";
const deletePayment = async (paymentId, paymentAppCredentials) => {
  const paymentApp = await appStore[paymentAppCredentials?.app?.dirName]?.();
  if (!paymentApp?.lib?.PaymentService) {
    console.warn(`payment App service of type ${paymentApp} is not implemented`);
    return false;
  }
  const PaymentService = paymentApp.lib.PaymentService;
  const paymentInstance = new PaymentService(paymentAppCredentials);
  const deleted = await paymentInstance.deletePayment(paymentId);
  return deleted;
};
const isVideoOrConferencingApp = (app) => app?.categories.includes(AppCategories.video) || app?.categories.includes(AppCategories.conferencing);
const getRemovedIntegrationNameFromAppSlug = (slug) => slug === "msteams" ? "office365_video" : slug.split("-")[0];
const locationsSchema = z__default.array(z__default.object({ type: z__default.string() }));
const handleDeleteCredential = async ({
  userId,
  userMetadata: userMetadata$1,
  credentialId,
  teamId
}) => {
  const credential = await prisma.credential.findFirst({
    where: {
      id: credentialId,
      ...teamId ? { teamId } : { userId }
    },
    select: {
      ...credentialForCalendarServiceSelect,
      app: {
        select: {
          slug: true,
          categories: true,
          dirName: true
        }
      }
    }
  });
  if (!credential) {
    throw new Error("Credential not found");
  }
  const eventTypes = await prisma.eventType.findMany({
    where: {
      OR: [
        {
          ...teamId ? { teamId } : { userId }
        },
        // for managed events
        {
          parent: {
            teamId
          }
        }
      ]
    },
    select: {
      id: true,
      locations: true,
      destinationCalendar: {
        include: {
          credential: true
        }
      },
      price: true,
      currency: true,
      metadata: true
    }
  });
  for (const eventType of eventTypes) {
    if (eventType.locations && isVideoOrConferencingApp(credential.app)) {
      const integrationQuery = getRemovedIntegrationNameFromAppSlug(credential.app?.slug ?? "");
      const locations = locationsSchema.parse(eventType.locations);
      const doesDailyVideoAlreadyExists = locations.some(
        (location) => location.type.includes(DailyLocationType)
      );
      const updatedLocations = locations.reduce((acc, location) => {
        if (location.type.includes(integrationQuery)) {
          if (!doesDailyVideoAlreadyExists)
            acc.push({ type: DailyLocationType });
        } else {
          acc.push(location);
        }
        return acc;
      }, []);
      await prisma.eventType.update({
        where: {
          id: eventType.id
        },
        data: {
          locations: updatedLocations
        }
      });
    }
    if (credential.app?.categories.includes(AppCategories.calendar) && eventType.destinationCalendar?.credential?.appId === credential.appId) {
      const destinationCalendar = await prisma.destinationCalendar.findUnique({
        where: {
          id: eventType.destinationCalendar?.id
        }
      });
      if (destinationCalendar) {
        await prisma.destinationCalendar.delete({
          where: {
            id: destinationCalendar.id
          }
        });
      }
    }
    if (credential.app?.categories.includes(AppCategories.crm)) {
      const metadata2 = EventTypeMetaDataSchema.parse(eventType.metadata);
      const appSlugToDelete = credential.app?.slug;
      const apps = eventTypeAppMetadataOptionalSchema.parse(metadata2?.apps);
      if (appSlugToDelete) {
        const appMetadata = removeAppFromEventTypeMetadata(appSlugToDelete, {
          apps
        });
        await prisma.$transaction(async () => {
          await prisma.eventType.update({
            where: {
              id: eventType.id
            },
            data: {
              hidden: true,
              metadata: {
                ...metadata2,
                apps: {
                  ...appMetadata
                }
              }
            }
          });
        });
      }
    }
    if (credential.app?.categories.includes(AppCategories.payment)) {
      const metadata2 = EventTypeMetaDataSchema.parse(eventType.metadata);
      const appSlug = credential.app?.slug;
      if (appSlug) {
        const apps = eventTypeAppMetadataOptionalSchema.parse(metadata2?.apps);
        const appMetadata = removeAppFromEventTypeMetadata(appSlug, {
          apps
        });
        await prisma.$transaction(async () => {
          await prisma.eventType.update({
            where: {
              id: eventType.id
            },
            data: {
              hidden: true,
              metadata: {
                ...metadata2,
                apps: {
                  ...appMetadata
                }
              }
            }
          });
          const unpaidBookings = await prisma.booking.findMany({
            where: {
              userId,
              eventTypeId: eventType.id,
              status: "PENDING",
              paid: false,
              payment: {
                every: {
                  success: false
                }
              }
            },
            select: {
              ...bookingMinimalSelect,
              recurringEventId: true,
              userId: true,
              responses: true,
              user: {
                select: {
                  id: true,
                  credentials: true,
                  email: true,
                  timeZone: true,
                  name: true,
                  destinationCalendar: true,
                  locale: true
                }
              },
              location: true,
              references: {
                select: {
                  uid: true,
                  type: true,
                  externalCalendarId: true
                }
              },
              payment: true,
              paid: true,
              eventType: {
                select: {
                  recurringEvent: true,
                  title: true,
                  bookingFields: true,
                  seatsPerTimeSlot: true,
                  seatsShowAttendees: true,
                  eventName: true,
                  hideOrganizerEmail: true,
                  team: {
                    select: {
                      id: true,
                      name: true
                    }
                  },
                  metadata: true
                }
              },
              uid: true,
              eventTypeId: true,
              destinationCalendar: true
            }
          });
          for (const booking of unpaidBookings) {
            await prisma.booking.update({
              where: {
                id: booking.id
              },
              data: {
                status: BookingStatus.CANCELLED,
                cancellationReason: "Payment method removed"
              }
            });
            for (const payment of booking.payment) {
              try {
                await deletePayment(payment.id, credential);
              } catch (e2) {
                console.error(e2);
              }
              await prisma.payment.delete({
                where: {
                  id: payment.id
                }
              });
            }
            await prisma.attendee.deleteMany({
              where: {
                bookingId: booking.id
              }
            });
            await prisma.bookingReference.deleteMany({
              where: {
                bookingId: booking.id
              }
            });
            const attendeesListPromises = booking.attendees.map(async (attendee) => {
              return {
                name: attendee.name,
                email: attendee.email,
                timeZone: attendee.timeZone,
                language: {
                  translate: await getTranslation(attendee.locale ?? "en", "common"),
                  locale: attendee.locale ?? "en"
                }
              };
            });
            const attendeesList = await Promise.all(attendeesListPromises);
            const tOrganizer = await getTranslation(booking?.user?.locale ?? "en", "common");
            await sendCancelledEmailsAndSMS(
              {
                type: booking?.eventType?.title,
                title: booking.title,
                description: booking.description,
                customInputs: isPrismaObjOrUndefined(booking.customInputs),
                ...getCalEventResponses({
                  bookingFields: booking.eventType?.bookingFields ?? null,
                  booking
                }),
                startTime: booking.startTime.toISOString(),
                endTime: booking.endTime.toISOString(),
                organizer: {
                  email: booking?.userPrimaryEmail ?? booking?.user?.email,
                  name: booking?.user?.name ?? "Nameless",
                  timeZone: booking?.user?.timeZone,
                  language: { translate: tOrganizer, locale: booking?.user?.locale ?? "en" }
                },
                attendees: attendeesList,
                uid: booking.uid,
                recurringEvent: parseRecurringEvent(booking.eventType?.recurringEvent),
                location: booking.location,
                destinationCalendar: booking.destinationCalendar ? [booking.destinationCalendar] : booking.user?.destinationCalendar ? [booking.user?.destinationCalendar] : [],
                cancellationReason: "Payment method removed by organizer",
                seatsPerTimeSlot: booking.eventType?.seatsPerTimeSlot,
                seatsShowAttendees: booking.eventType?.seatsShowAttendees,
                hideOrganizerEmail: booking.eventType?.hideOrganizerEmail,
                team: !!booking.eventType?.team ? {
                  name: booking.eventType.team.name,
                  id: booking.eventType.team.id,
                  members: []
                } : void 0
              },
              {
                eventName: booking?.eventType?.eventName
              },
              booking?.eventType?.metadata
            );
          }
        });
      }
    } else if (appStoreMetadata[credential.app?.slug]?.extendsFeature === "EventType") {
      const metadata2 = eventTypeMetaDataSchemaWithTypedApps.parse(eventType.metadata);
      const appSlug = credential.app?.slug;
      if (appSlug) {
        await prisma.eventType.update({
          where: {
            id: eventType.id
          },
          data: {
            hidden: true,
            metadata: {
              ...metadata2,
              apps: {
                ...metadata2?.apps,
                [appSlug]: void 0
              }
            }
          }
        });
      }
    }
  }
  if (credential.app?.slug === "zapier") {
    await prisma.apiKey.deleteMany({
      where: {
        userId,
        appId: "zapier"
      }
    });
    await prisma.webhook.deleteMany({
      where: {
        userId,
        appId: "zapier"
      }
    });
    deleteWebhookScheduledTriggers({
      appId: credential.appId,
      userId: teamId ? void 0 : userId,
      teamId
    });
  }
  let metadata = userMetadata.parse(userMetadata$1);
  if (credential.app?.slug === metadata?.defaultConferencingApp?.appSlug) {
    metadata = {
      ...metadata,
      defaultConferencingApp: void 0
    };
    await prisma.user.update({
      where: {
        id: userId
      },
      data: {
        metadata
      }
    });
  }
  if (credential.app?.categories.includes(AppCategories.calendar)) {
    try {
      const calendar = await getCalendar(buildNonDelegationCredential(credential));
      const calendars = await calendar?.listCalendars();
      const calendarIds = calendars?.map((cal) => cal.externalId);
      await prisma.selectedCalendar.deleteMany({
        where: {
          userId,
          integration: credential.type,
          externalId: {
            in: calendarIds
          }
        }
      });
    } catch (error) {
      console.warn(
        `Error deleting selected calendars for userId: ${userId} integration: ${credential.type}`,
        error
      );
    }
  }
  await prisma.credential.delete({
    where: {
      id: credentialId
    }
  });
};
const removeAppFromEventTypeMetadata = (appSlugToDelete, eventTypeMetadata) => {
  const appMetadata = eventTypeMetadata?.apps ? Object.entries(eventTypeMetadata.apps).reduce((filteredApps, [appName, appData]) => {
    if (appName !== appSlugToDelete) {
      filteredApps[appName] = appData;
    }
    return filteredApps;
  }, {}) : {};
  return appMetadata;
};
const handleDeleteCredential$1 = handleDeleteCredential;
const safeWorkspacePlatformSelect = {
  id: true,
  name: true,
  enabled: true,
  slug: true,
  description: true
};
const workspacePlatformSelectWithServiceAccountKey = {
  ...safeWorkspacePlatformSelect,
  defaultServiceAccountKey: true
};
class WorkspacePlatformRepository {
  static withParsedServiceAccountKey(data) {
    return {
      ...data,
      defaultServiceAccountKey: serviceAccountKeySchema.parse(data.defaultServiceAccountKey)
    };
  }
  static async create(data) {
    const { defaultServiceAccountKey: _defaultServiceAccountKey, ...rest } = data;
    const defaultServiceAccountKey = _defaultServiceAccountKey === void 0 || _defaultServiceAccountKey === null ? Prisma.JsonNull : _defaultServiceAccountKey;
    return await prisma.workspacePlatform.create({
      data: {
        defaultServiceAccountKey,
        ...rest
      },
      select: safeWorkspacePlatformSelect
    });
  }
  static async findAll() {
    return await prisma.workspacePlatform.findMany({
      select: safeWorkspacePlatformSelect
    });
  }
  static async findAllBySlug({ slug }) {
    return await prisma.workspacePlatform.findMany({
      where: { slug },
      select: safeWorkspacePlatformSelect
    });
  }
  static async findBySlug({ slug }) {
    return await prisma.workspacePlatform.findUnique({
      where: { slug },
      select: safeWorkspacePlatformSelect
    });
  }
  static async findBySlugIncludeSensitiveServiceAccountKey({ slug }) {
    const workspacePlatform = await prisma.workspacePlatform.findUnique({
      where: { slug },
      select: workspacePlatformSelectWithServiceAccountKey
    });
    if (!workspacePlatform) {
      return null;
    }
    return this.withParsedServiceAccountKey(workspacePlatform);
  }
  static async updateById({
    id,
    data
  }) {
    return await prisma.workspacePlatform.update({
      where: { id },
      data,
      select: safeWorkspacePlatformSelect
    });
  }
}
const log$2 = logger.getSubLogger({ prefix: ["delegationCredential/utils"] });
class InvalidServiceAccountKeyError extends Error {
  constructor(message) {
    super(message);
    this.name = "InvalidServiceAccountKeyError";
  }
}
async function ensureDelegationCredentialNotAlreadyConfigured({
  domain,
  currentOrganizationId,
  delegationCredentialBeingUpdatedId
}) {
  const allDelegationsForDomain = await DelegationCredentialRepository.findAllByDomain({
    domain
  });
  const conflictingDelegationInCurrentOrg = allDelegationsForDomain.find(
    (delegation) => delegation.organizationId === currentOrganizationId && delegation.id !== delegationCredentialBeingUpdatedId
  );
  if (conflictingDelegationInCurrentOrg) {
    throw new TRPCError({
      code: "BAD_REQUEST",
      message: `Your organization already has delegation credential for ${conflictingDelegationInCurrentOrg.domain}`
    });
  }
  const differentOrgEnabledDelegations = allDelegationsForDomain.filter(
    (delegation) => delegation.organizationId !== currentOrganizationId && delegation.enabled
  );
  if (differentOrgEnabledDelegations.length > 0) {
    throw new TRPCError({
      code: "BAD_REQUEST",
      message: `Domain ${domain} already has delegation credential enabled in another organization`
    });
  }
}
const handleDelegationCredentialError = (error) => {
  if (error instanceof InvalidServiceAccountKeyError) {
    throw new TRPCError({
      code: "BAD_REQUEST",
      message: error.message
    });
  }
  if (error instanceof TRPCError) {
    throw error;
  }
  log$2.error("Error handling delegation credential:", safeStringify(error));
  throw new TRPCError({
    code: "INTERNAL_SERVER_ERROR",
    message: "An error occurred while handling delegation credential settings."
  });
};
const ensureNoServiceAccountKey = (delegationCredential) => {
  if (!delegationCredential) {
    return null;
  }
  const { serviceAccountKey: _1, ...rest } = delegationCredential;
  return {
    ...rest,
    serviceAccountKey: void 0
  };
};
async function handler({
  input,
  ctx
}) {
  const { workspacePlatformSlug, domain, serviceAccountKey } = input;
  const { user } = ctx;
  const { organizationId } = user;
  if (!organizationId) {
    throw new TRPCError({
      code: "UNAUTHORIZED",
      message: "You must be part of an organization to add a delegation credential"
    });
  }
  try {
    const workspacePlatform = await WorkspacePlatformRepository.findBySlug({
      slug: workspacePlatformSlug
    });
    if (!workspacePlatform) {
      throw new TRPCError({
        code: "NOT_FOUND",
        message: `Workspace platform ${workspacePlatformSlug} not found`
      });
    }
    await ensureDelegationCredentialNotAlreadyConfigured({
      domain,
      currentOrganizationId: organizationId,
      delegationCredentialBeingUpdatedId: null
    });
    const createdDelegation = await DelegationCredentialRepository.create({
      workspacePlatformId: workspacePlatform.id,
      domain,
      // We don't want to enable by default because enabling requires some checks to be completed and it has a separate flow.
      enabled: false,
      organizationId,
      serviceAccountKey
    });
    return ensureNoServiceAccountKey(createdDelegation);
  } catch (error) {
    handleDelegationCredentialError(error);
  }
}
const getInstallCountPerApp = async () => {
  const mostPopularApps = z.array(z.object({ appId: z.string(), installCount: z.number() })).parse(
    await prisma.$queryRaw`
    SELECT
      c."appId",
      COUNT(*)::integer AS "installCount"
    FROM
      "Credential" c
    WHERE
      c."appId" IS NOT NULL
    GROUP BY
      c."appId"
    ORDER BY
      "installCount" DESC
    `
  );
  return mostPopularApps.reduce((acc, { appId, installCount }) => {
    acc[appId] = installCount;
    return acc;
  }, {});
};
async function getConnectedApps({
  user,
  prisma: prisma2,
  input
}) {
  const {
    variant,
    exclude,
    onlyInstalled,
    includeTeamInstalledApps,
    extendsFeature,
    teamId,
    sortByMostPopular,
    sortByInstalledFirst,
    appId
  } = input;
  let credentials = await getUsersCredentialsIncludeServiceAccountKey(user);
  let userTeams = [];
  if (includeTeamInstalledApps || teamId) {
    const teamsQuery = await prisma2.team.findMany({
      where: {
        members: {
          some: {
            userId: user.id,
            accepted: true
          }
        }
      },
      select: {
        id: true,
        credentials: {
          select: credentialForCalendarServiceSelect
        },
        name: true,
        logoUrl: true,
        members: {
          where: {
            userId: user.id
          },
          select: {
            role: true
          }
        },
        parent: {
          select: {
            id: true,
            credentials: {
              select: credentialForCalendarServiceSelect
            },
            name: true,
            logoUrl: true,
            members: {
              where: {
                userId: user.id
              },
              select: {
                role: true
              }
            }
          }
        }
      }
    });
    const parentTeams = [];
    if (teamId) {
      teamsQuery.forEach((team) => {
        if (team?.parent) {
          const { parent, ...filteredTeam } = team;
          if (!teamsQuery.some((t) => t.id === parent.id)) {
            parentTeams.push(parent);
          }
        }
      });
    }
    userTeams = [...teamsQuery, ...parentTeams];
    const teamAppCredentials = userTeams.flatMap((teamApp) => {
      return teamApp.credentials ? buildNonDelegationCredentials(teamApp.credentials.flat()) : [];
    });
    if (!includeTeamInstalledApps || teamId) {
      credentials = teamAppCredentials;
    } else {
      credentials = credentials.concat(teamAppCredentials);
    }
  }
  const enabledApps = await getEnabledAppsFromCredentials(credentials, {
    filterOnCredentials: onlyInstalled,
    ...appId ? { where: { slug: appId } } : {}
  });
  let apps = await Promise.all(
    enabledApps.map(async ({ credentials: _, credential, key: _2, ...app }) => {
      const userCredentialIds = credentials.filter((c2) => c2.appId === app.slug && !c2.teamId).map((c2) => c2.id);
      const invalidCredentialIds = credentials.filter((c2) => c2.appId === app.slug && c2.invalid).map((c2) => c2.id);
      const teams = await Promise.all(
        credentials.filter((c2) => c2.appId === app.slug && c2.teamId).map(async (c2) => {
          const team = userTeams.find((team2) => team2.id === c2.teamId);
          if (!team) {
            return null;
          }
          return {
            teamId: team.id,
            name: team.name,
            logoUrl: team.logoUrl,
            credentialId: c2.id,
            isAdmin: checkAdminOrOwner(team.members[0].role)
          };
        })
      );
      const credentialOwner = {
        name: user.name,
        avatar: user?.avatar ?? user?.avatarUrl
      };
      let isSetupAlready = void 0;
      if (credential && app.categories.includes("payment")) {
        const paymentApp = await appStore[app.dirName]?.();
        if (paymentApp && "lib" in paymentApp && paymentApp?.lib && "PaymentService" in paymentApp?.lib) {
          const PaymentService = paymentApp.lib.PaymentService;
          const paymentInstance = new PaymentService(credential);
          isSetupAlready = paymentInstance.isSetupAlready();
        }
      }
      let dependencyData = [];
      if (app.dependencies?.length) {
        dependencyData = app.dependencies.map((dependency) => {
          const dependencyInstalled = enabledApps.some(
            (dbAppIterator) => dbAppIterator.credentials.length && dbAppIterator.slug === dependency
          );
          const dependencyName = getAppFromSlug(dependency)?.name;
          return { name: dependencyName, installed: dependencyInstalled };
        });
      }
      return {
        ...app,
        ...teams.length && {
          credentialOwner
        },
        userCredentialIds,
        invalidCredentialIds,
        teams,
        isInstalled: !!userCredentialIds.length || !!teams.length || app.isGlobal,
        isSetupAlready,
        ...app.dependencies && { dependencyData }
      };
    })
  );
  if (variant) {
    apps = apps.flatMap((item) => item.variant.startsWith(variant) ? [item] : []);
  }
  if (exclude) {
    apps = apps.filter((item) => exclude ? !exclude.includes(item.variant) : true);
  }
  if (onlyInstalled) {
    apps = apps.flatMap(
      (item) => item.userCredentialIds.length > 0 || item.teams.length || item.isGlobal ? [item] : []
    );
  }
  if (extendsFeature) {
    apps = apps.filter((app) => app.extendsFeature?.includes(extendsFeature)).map((app) => ({
      ...app,
      isInstalled: !!app.userCredentialIds?.length || !!app.teams?.length || app.isGlobal
    }));
  }
  if (sortByMostPopular) {
    const installCountPerApp = await getInstallCountPerApp();
    apps.sort((a2, b4) => {
      const aCount = installCountPerApp[a2.slug] || 0;
      const bCount = installCountPerApp[b4.slug] || 0;
      return bCount - aCount;
    });
  }
  if (sortByInstalledFirst) {
    apps.sort((a2, b4) => {
      return (a2.isInstalled ? 0 : 1) - (b4.isInstalled ? 0 : 1);
    });
  }
  return {
    items: apps
  };
}
const log$1 = logger.getSubLogger({ prefix: ["[DelegationCredential]"] });
async function getAffectedMembersForDisable({
  delegationCredentialId
}) {
  const delegationCredential = await DelegationCredentialRepository.findById({ id: delegationCredentialId });
  if (!delegationCredential) {
    return [];
  }
  const lastEnabledAt = delegationCredential.lastEnabledAt;
  if (!lastEnabledAt) {
    log$1.info(
      `Delegation credential ${delegationCredentialId} has no lastEnabledAt, so assuming no members were affected`
    );
    return [];
  }
  const membershipsThatCouldPotentiallyBeAffected = await MembershipRepository.findMembershipsCreatedAfterTimeIncludeUser({
    organizationId: delegationCredential.organizationId,
    time: lastEnabledAt
  });
  return membershipsThatCouldPotentiallyBeAffected.map((membership) => ({
    email: membership.user.email,
    name: membership.user.name,
    id: membership.user.id
  }));
}
const log = logger.getSubLogger({ prefix: ["viewer", "delegationCredential", "toggleEnabled"] });
async function toggleDelegationCredentialEnabled(loggedInUser, input) {
  const currentDelegationCredential = await DelegationCredentialRepository.findById({
    id: input.id
  });
  if (!currentDelegationCredential) {
    throw new Error("Delegation credential not found");
  }
  const shouldBeEnabled = input.enabled;
  if (shouldBeEnabled === currentDelegationCredential.enabled) {
    return currentDelegationCredential;
  }
  if (shouldBeEnabled) {
    await assertWorkspaceConfigured({
      delegationCredentialId: input.id,
      user: loggedInUser
    });
  }
  if (!shouldBeEnabled) {
    const affectedMemberships = await getAffectedMembersForDisable({ delegationCredentialId: input.id });
    const slug = currentDelegationCredential.workspacePlatform?.slug;
    if (!slug) {
      log.error(`Delegation credential ${input.id} has no workspace platform slug`);
    }
    let calendarAppName;
    let conferencingAppName;
    if (slug === "google") {
      calendarAppName = "Google Calendar";
      conferencingAppName = "Google Meet";
    } else if (slug === "microsoft") {
      calendarAppName = "Microsoft 365";
      conferencingAppName = "Microsoft Teams";
    } else {
      throw new Error(`Unsupported workspace platform slug: ${slug}`);
    }
    for (const membership of affectedMemberships) {
      if (membership.email) {
        await sendDelegationCredentialDisabledEmail({
          recipientEmail: membership.email,
          recipientName: membership.name || void 0,
          calendarAppName,
          conferencingAppName
        });
      }
    }
  }
  const updatedDelegationCredential = await DelegationCredentialRepository.updateById({
    id: input.id,
    data: {
      enabled: shouldBeEnabled,
      // Don't touch lastEnabledAt if we are disabling
      lastEnabledAt: shouldBeEnabled ? /* @__PURE__ */ new Date() : void 0,
      // Don't touch lastDisabledAt if we are enabling
      lastDisabledAt: shouldBeEnabled ? void 0 : /* @__PURE__ */ new Date()
    }
  });
  return ensureNoServiceAccountKey(updatedDelegationCredential);
}
const assertWorkspaceConfigured = async ({
  delegationCredentialId,
  user
}) => {
  const delegationCredential = await DelegationCredentialRepository.findByIdIncludeSensitiveServiceAccountKey(
    {
      id: delegationCredentialId
    }
  );
  if (!delegationCredential) {
    throw new Error("Domain wide delegation not found");
  }
  if (!hasServiceAccountKey(delegationCredential)) {
    throw new Error("Domain wide delegation doesn't have service account key");
  }
  const isSuccessfullyConfigured = await checkIfSuccessfullyConfiguredInWorkspace({
    delegationCredential,
    user
  });
  if (!isSuccessfullyConfigured) {
    throw new Error("Workspace not successfully configured");
  }
};
function hasServiceAccountKey(delegationCredential) {
  return delegationCredential.serviceAccountKey !== null;
}
export {
  d as CalendarAppDelegationCredentialClientIdNotAuthorizedError,
  b2 as CalendarAppDelegationCredentialConfigurationError,
  C as CalendarAppDelegationCredentialError,
  a as CalendarAppDelegationCredentialInvalidGrantError,
  e as CalendarAppDelegationCredentialNotSetupError,
  c as CalendarAppError,
  A as CalendarService,
  DelegationCredentialRepository,
  I as IcsFeedCalendarService,
  b3 as OAuth2UniversalSchema,
  handler as addDelegationCredential,
  b as enrichUserWithDelegationConferencingCredentialsWithoutOrgId,
  getAppFromSlug,
  g as getApps,
  getConnectedApps,
  getEnabledAppsFromCredentials,
  getUsersCredentialsIncludeServiceAccountKey,
  handleDeleteCredential$1 as handleDeleteCredential,
  toggleDelegationCredentialEnabled
};
