import { ac as isAuthorized, ad as isAuthorizedToAddActiveOnIds, ae as deleteRemindersOfActiveOnIds, af as scheduleWorkflowNotifications, ag as getSender, ah as WorkflowRepository, ai as isStepEdited, aj as isEmailAction, ak as getEmailTemplateText, al as verifyEmailSender, am as tasker, an as removeSmsReminderFieldForEventTypes, ao as upsertSmsReminderFieldForEventTypes } from "./email-manager-ED8hrFPG.js";
import { y as IS_SELF_HOSTED, p as prisma, z as WorkflowTemplates, e as WorkflowActions, E as SCANNING_WORKFLOW_STEPS } from "./index-Cw1zbw54.js";
import { i as isPrismaObj } from "./isPrismaObj-NqBB0qe9.js";
import { TRPCError } from "@trpc/server";
import { I as InternalTeamBilling } from "./internal-team-billing-QYfS1a6b.js";
const hasKeyInMetadata = (x, key) => isPrismaObj(x?.metadata) && !!x?.metadata && key in x.metadata;
const hasActiveTeamPlanHandler = async ({ ctx }) => {
  if (IS_SELF_HOSTED)
    return { isActive: true, isTrial: false };
  const teams = await prisma.team.findMany({
    where: {
      members: {
        some: {
          userId: ctx.user.id,
          accepted: true
        }
      }
    }
  });
  if (!teams.length)
    return { isActive: false, isTrial: false };
  let isTrial = false;
  for (const team of teams) {
    if (team.isPlatform && team.isOrganization) {
      const platformBilling = await prisma.platformBilling.findUnique({ where: { id: team.id } });
      if (platformBilling && platformBilling.plan !== "none" && platformBilling.plan !== "FREE") {
        return { isActive: true, isTrial: false };
      }
    }
    const teamBillingService = new InternalTeamBilling(team);
    const subscriptionStatus = await teamBillingService.getSubscriptionStatus();
    if (subscriptionStatus === "active" || subscriptionStatus === "past_due") {
      return { isActive: true, isTrial: false };
    }
    if (subscriptionStatus === "trialing") {
      isTrial = true;
    }
  }
  return { isActive: false, isTrial };
};
const hasActiveTeamPlanHandler$1 = hasActiveTeamPlanHandler;
const updateHandler = async ({ ctx, input }) => {
  const { user } = ctx;
  const { id, name, activeOn, steps, trigger, time, timeUnit, isActiveOnAll } = input;
  const userWorkflow = await ctx.prisma.workflow.findUnique({
    where: {
      id
    },
    select: {
      id: true,
      userId: true,
      isActiveOnAll: true,
      trigger: true,
      time: true,
      timeUnit: true,
      team: {
        select: {
          isOrganization: true
        }
      },
      teamId: true,
      user: {
        select: {
          teams: true
        }
      },
      steps: true,
      activeOn: true,
      activeOnTeams: true
    }
  });
  const isOrg = !!userWorkflow?.team?.isOrganization;
  const isUserAuthorized = await isAuthorized(userWorkflow, ctx.user.id, true);
  if (!isUserAuthorized || !userWorkflow) {
    throw new TRPCError({ code: "UNAUTHORIZED" });
  }
  if (steps.find((step) => step.workflowId != id)) {
    throw new TRPCError({ code: "UNAUTHORIZED" });
  }
  const isCurrentUsernamePremium = hasKeyInMetadata(user, "isPremium") ? !!user.metadata.isPremium : false;
  let teamsPlan = { isActive: false, isTrial: false };
  if (!isCurrentUsernamePremium) {
    teamsPlan = await hasActiveTeamPlanHandler$1({ ctx });
  }
  const hasPaidPlan = IS_SELF_HOSTED || isCurrentUsernamePremium || teamsPlan.isActive;
  let newActiveOn = [];
  let removedActiveOnIds = [];
  let activeOnWithChildren = activeOn;
  let oldActiveOnIds = [];
  if (!isOrg) {
    const activeOnEventTypes = await ctx.prisma.eventType.findMany({
      where: {
        id: {
          in: activeOn
        },
        ...userWorkflow.teamId && { parentId: null }
        //all children managed event types are added after
      },
      select: {
        id: true,
        children: {
          select: {
            id: true
          }
        }
      }
    });
    activeOnWithChildren = activeOnEventTypes.map((eventType) => [eventType.id].concat(eventType.children.map((child) => child.id))).flat();
    let oldActiveOnEventTypes;
    if (userWorkflow.isActiveOnAll) {
      oldActiveOnEventTypes = await ctx.prisma.eventType.findMany({
        where: {
          ...userWorkflow.teamId ? { teamId: userWorkflow.teamId } : { userId: userWorkflow.userId }
        },
        select: {
          id: true,
          children: {
            select: {
              id: true
            }
          }
        }
      });
    } else {
      oldActiveOnEventTypes = (await ctx.prisma.workflowsOnEventTypes.findMany({
        where: {
          workflowId: id
        },
        select: {
          eventTypeId: true,
          eventType: {
            select: {
              children: {
                select: {
                  id: true
                }
              }
            }
          }
        }
      })).map((eventTypeRel) => {
        return { id: eventTypeRel.eventTypeId, children: eventTypeRel.eventType.children };
      });
    }
    oldActiveOnIds = oldActiveOnEventTypes.flatMap((eventType) => [
      eventType.id,
      ...eventType.children.map((child) => child.id)
    ]);
    newActiveOn = activeOn.filter((eventTypeId) => !oldActiveOnIds.includes(eventTypeId));
    const isAuthorizedToAddIds = await isAuthorizedToAddActiveOnIds(
      newActiveOn,
      isOrg,
      userWorkflow?.teamId,
      userWorkflow?.userId
    );
    if (!isAuthorizedToAddIds) {
      throw new TRPCError({ code: "UNAUTHORIZED" });
    }
    removedActiveOnIds = oldActiveOnIds.filter((eventTypeId) => !activeOnWithChildren.includes(eventTypeId));
    await deleteRemindersOfActiveOnIds({ removedActiveOnIds, workflowSteps: userWorkflow.steps, isOrg });
    await ctx.prisma.workflowsOnEventTypes.deleteMany({
      where: {
        workflowId: id
      }
    });
    await ctx.prisma.workflowsOnEventTypes.createMany({
      data: activeOnWithChildren.map((eventTypeId) => ({
        workflowId: id,
        eventTypeId
      }))
    });
  } else {
    if (userWorkflow.isActiveOnAll) {
      oldActiveOnIds = (await ctx.prisma.team.findMany({
        where: {
          parent: {
            id: userWorkflow.teamId ?? 0
          }
        },
        select: {
          id: true
        }
      })).map((team) => team.id);
    } else {
      oldActiveOnIds = (await ctx.prisma.workflowsOnTeams.findMany({
        where: {
          workflowId: id
        },
        select: {
          teamId: true
        }
      })).map((teamRel) => teamRel.teamId);
    }
    newActiveOn = activeOn.filter((teamId) => !oldActiveOnIds.includes(teamId));
    const isAuthorizedToAddIds = await isAuthorizedToAddActiveOnIds(
      newActiveOn,
      isOrg,
      userWorkflow?.teamId,
      userWorkflow?.userId
    );
    if (!isAuthorizedToAddIds) {
      throw new TRPCError({ code: "UNAUTHORIZED" });
    }
    removedActiveOnIds = oldActiveOnIds.filter((teamId) => !activeOn.includes(teamId));
    await deleteRemindersOfActiveOnIds({
      removedActiveOnIds,
      workflowSteps: userWorkflow.steps,
      isOrg,
      activeOnIds: activeOn.filter((activeOn2) => !newActiveOn.includes(activeOn2))
    });
    await ctx.prisma.workflowsOnTeams.deleteMany({
      where: {
        workflowId: id
      }
    });
    await ctx.prisma.workflowsOnTeams.createMany({
      data: activeOn.map((teamId) => ({
        workflowId: id,
        teamId
      }))
    });
  }
  if (userWorkflow.trigger !== trigger || userWorkflow.time !== time || userWorkflow.timeUnit !== timeUnit) {
    await deleteRemindersOfActiveOnIds({
      removedActiveOnIds: oldActiveOnIds,
      workflowSteps: userWorkflow.steps,
      isOrg
    });
    await scheduleWorkflowNotifications({
      activeOn,
      // schedule for activeOn that stayed the same + new active on (old reminders were deleted)
      isOrg,
      workflowSteps: userWorkflow.steps,
      // use old steps here, edited and deleted steps are handled below
      time,
      timeUnit,
      trigger,
      userId: user.id,
      teamId: userWorkflow.teamId
    });
  } else {
    await scheduleWorkflowNotifications({
      activeOn: newActiveOn,
      isOrg,
      workflowSteps: userWorkflow.steps,
      // use old steps here, edited and deleted steps are handled below
      time,
      timeUnit,
      trigger,
      userId: user.id,
      teamId: userWorkflow.teamId,
      alreadyScheduledActiveOnIds: activeOn.filter((activeOn2) => !newActiveOn.includes(activeOn2))
      // alreadyScheduledActiveOnIds
    });
  }
  userWorkflow.steps.map(async (oldStep) => {
    const foundStep = steps.find((s) => s.id === oldStep.id);
    let newStep;
    if (foundStep) {
      const { senderName, ...rest } = {
        ...foundStep,
        numberVerificationPending: false,
        sender: getSender({
          action: foundStep.action,
          sender: foundStep.sender || null,
          senderName: foundStep.senderName
        })
      };
      newStep = rest;
    }
    const remindersFromStep = await ctx.prisma.workflowReminder.findMany({
      where: {
        workflowStepId: oldStep.id
      },
      select: {
        id: true,
        referenceId: true,
        method: true,
        booking: {
          select: {
            eventTypeId: true
          }
        }
      }
    });
    if (!newStep) {
      await WorkflowRepository.deleteAllWorkflowReminders(remindersFromStep);
      await ctx.prisma.workflowStep.delete({
        where: {
          id: oldStep.id
        }
      });
    } else if (isStepEdited(oldStep, { ...newStep, verifiedAt: oldStep.verifiedAt })) {
      if (!hasPaidPlan && isEmailAction(newStep.action)) {
        const isChangingToCustomTemplate = newStep.template === WorkflowTemplates.CUSTOM && oldStep.template !== WorkflowTemplates.CUSTOM;
        if (isChangingToCustomTemplate) {
          throw new TRPCError({ code: "UNAUTHORIZED", message: "Not available on free plan" });
        }
        if (newStep.emailSubject !== oldStep.emailSubject || newStep.reminderBody !== oldStep.reminderBody) {
          if (newStep.template === WorkflowTemplates.CUSTOM) {
            throw new TRPCError({ code: "UNAUTHORIZED", message: "Not available on free plan" });
          }
          const { emailBody, emailSubject } = await getEmailTemplateText(newStep.template, {
            locale: ctx.user.locale,
            action: newStep.action,
            timeFormat: ctx.user.timeFormat
          });
          newStep = { ...newStep, reminderBody: emailBody, emailSubject };
        }
      }
      const requiresSender = newStep.action === WorkflowActions.SMS_NUMBER || newStep.action === WorkflowActions.WHATSAPP_NUMBER || newStep.action === WorkflowActions.EMAIL_ADDRESS;
      if (newStep.action === WorkflowActions.EMAIL_ADDRESS) {
        await verifyEmailSender(newStep.sendTo || "", user.id, userWorkflow.teamId);
      }
      const didBodyChange = newStep.reminderBody !== oldStep.reminderBody;
      await ctx.prisma.workflowStep.update({
        where: {
          id: oldStep.id
        },
        data: {
          action: newStep.action,
          sendTo: requiresSender ? newStep.sendTo : null,
          stepNumber: newStep.stepNumber,
          workflowId: newStep.workflowId,
          reminderBody: newStep.reminderBody,
          emailSubject: newStep.emailSubject,
          template: newStep.template,
          numberRequired: newStep.numberRequired,
          sender: newStep.sender,
          numberVerificationPending: false,
          includeCalendarEvent: newStep.includeCalendarEvent,
          verifiedAt: !SCANNING_WORKFLOW_STEPS ? /* @__PURE__ */ new Date() : didBodyChange ? null : oldStep.verifiedAt
        }
      });
      if (SCANNING_WORKFLOW_STEPS && didBodyChange) {
        await tasker.create("scanWorkflowBody", {
          workflowStepId: oldStep.id,
          userId: ctx.user.id,
          createdAt: (/* @__PURE__ */ new Date()).toISOString()
        });
      } else {
        await scheduleWorkflowNotifications({
          activeOn,
          isOrg,
          workflowSteps: [newStep],
          time,
          timeUnit,
          trigger,
          userId: user.id,
          teamId: userWorkflow.teamId
        });
      }
      await WorkflowRepository.deleteAllWorkflowReminders(remindersFromStep);
    }
  });
  const addedSteps = await Promise.all(
    steps.filter((step) => step.id <= 0).map(async (newStep) => {
      if (!hasPaidPlan && isEmailAction(newStep.action)) {
        if (newStep.template === WorkflowTemplates.CUSTOM) {
          throw new TRPCError({ code: "UNAUTHORIZED", message: "Not available on free plan" });
        }
        const { emailBody, emailSubject } = await getEmailTemplateText(newStep.template, {
          locale: ctx.user.locale,
          action: newStep.action,
          timeFormat: ctx.user.timeFormat
        });
        newStep = { ...newStep, reminderBody: emailBody, emailSubject };
      }
      if (newStep.action === WorkflowActions.EMAIL_ADDRESS) {
        await verifyEmailSender(newStep.sendTo || "", user.id, userWorkflow.teamId);
      }
      const {
        id: _stepId,
        senderName,
        ...stepToAdd
      } = {
        ...newStep,
        sender: getSender({
          action: newStep.action,
          sender: newStep.sender || null,
          senderName: newStep.senderName
        })
      };
      return stepToAdd;
    })
  );
  if (addedSteps.length) {
    const createdSteps = await Promise.all(
      addedSteps.map(
        (step) => ctx.prisma.workflowStep.create({
          data: {
            ...step,
            numberVerificationPending: false,
            ...!SCANNING_WORKFLOW_STEPS ? { verifiedAt: /* @__PURE__ */ new Date() } : {}
          }
        })
      )
    );
    if (SCANNING_WORKFLOW_STEPS) {
      await Promise.all(
        createdSteps.map(
          (step) => tasker.create("scanWorkflowBody", {
            workflowStepId: step.id,
            userId: ctx.user.id,
            createdAt: (/* @__PURE__ */ new Date()).toISOString()
          })
        )
      );
    } else {
      await scheduleWorkflowNotifications({
        activeOn,
        isOrg,
        workflowSteps: createdSteps,
        time,
        timeUnit,
        trigger,
        userId: user.id,
        teamId: userWorkflow.teamId
      });
    }
  }
  await ctx.prisma.workflow.update({
    where: {
      id
    },
    data: {
      name,
      trigger,
      time,
      timeUnit,
      isActiveOnAll
    }
  });
  const workflow = await ctx.prisma.workflow.findUnique({
    where: {
      id
    },
    include: {
      activeOn: {
        select: {
          eventType: true
        }
      },
      activeOnTeams: {
        select: {
          team: true
        }
      },
      team: {
        select: {
          id: true,
          slug: true,
          members: true,
          name: true,
          isOrganization: true
        }
      },
      steps: {
        orderBy: {
          stepNumber: "asc"
        }
      }
    }
  });
  const smsReminderNumberNeeded = activeOn.length && steps.some(
    (step) => step.action === WorkflowActions.SMS_ATTENDEE || step.action === WorkflowActions.WHATSAPP_ATTENDEE
  );
  await removeSmsReminderFieldForEventTypes({
    activeOnToRemove: removedActiveOnIds,
    workflowId: id,
    isOrg,
    activeOn
  });
  if (!smsReminderNumberNeeded) {
    await removeSmsReminderFieldForEventTypes({
      activeOnToRemove: activeOnWithChildren,
      workflowId: id,
      isOrg
    });
  } else {
    await upsertSmsReminderFieldForEventTypes({
      activeOn: activeOnWithChildren,
      workflowId: id,
      isSmsReminderNumberRequired: steps.some(
        (s) => (s.action === WorkflowActions.SMS_ATTENDEE || s.action === WorkflowActions.WHATSAPP_ATTENDEE) && s.numberRequired
      ),
      isOrg
    });
  }
  return {
    workflow
  };
};
export {
  updateHandler as updateWorkflow
};
