import BadDataException from "../../Types/Exception/BadDataException";
import DatabaseService from "./DatabaseService";
import Model from "../../Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule";
import OnCallDutyPolicyService from "./OnCallDutyPolicyService";
import EmailTemplateType from "../../Types/Email/EmailTemplateType";
import UserNotificationSettingService from "./UserNotificationSettingService";
import NotificationSettingEventType from "../../Types/NotificationSetting/NotificationSettingEventType";
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
import OnCallDutyPolicyScheduleService from "./OnCallDutyPolicyScheduleService";
import OnCallDutyPolicyFeedService from "./OnCallDutyPolicyFeedService";
import { OnCallDutyPolicyFeedEventType } from "../../Models/DatabaseModels/OnCallDutyPolicyFeed";
import { Gray500, Red500 } from "../../Types/BrandColors";
import PushNotificationUtil from "../Utils/PushNotificationUtil";
import { createWhatsAppMessageFromTemplate } from "../Utils/WhatsAppTemplateUtil";
export class Service extends DatabaseService {
    constructor() {
        super(Model);
    }
    async onCreateSuccess(_onCreate, createdItem) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
        const createdItemId = createdItem.id;
        if (!createdItemId) {
            throw new BadDataException("Created item does not have an ID");
        }
        const createdModel = await this.findOneById({
            id: createdItemId,
            select: {
                projectId: true,
                onCallDutyPolicyScheduleId: true,
                onCallDutyPolicySchedule: {
                    name: true,
                },
                onCallDutyPolicyEscalationRule: {
                    name: true,
                    _id: true,
                    order: true,
                },
                onCallDutyPolicy: {
                    name: true,
                    _id: true,
                },
                createdByUserId: true,
            },
            props: {
                isRoot: true,
            },
        });
        if (!createdModel) {
            throw new BadDataException("Created item does not have an ID");
        }
        if (!createdModel.onCallDutyPolicyScheduleId) {
            throw new BadDataException("Created item does not have a onCallDutyPolicyScheduleId");
        }
        // send notification to the new current user.
        const userOnSchedule = await OnCallDutyPolicyScheduleService.getCurrentUserIdInSchedule(createdModel.onCallDutyPolicyScheduleId, {
            onCallDutyPolicyId: ((_a = createdModel.onCallDutyPolicy) === null || _a === void 0 ? void 0 : _a.id) || undefined,
        });
        if (!userOnSchedule) {
            return createdItem;
        }
        const scheduleName = ((_b = createdModel.onCallDutyPolicySchedule) === null || _b === void 0 ? void 0 : _b.name) || "No name provided";
        const sendEmailToUserId = userOnSchedule;
        if (!sendEmailToUserId) {
            return createdItem;
        }
        if (!createdModel) {
            return createdItem;
        }
        const vars = {
            onCallPolicyName: ((_c = createdModel.onCallDutyPolicy) === null || _c === void 0 ? void 0 : _c.name) || "No name provided",
            escalationRuleName: ((_d = createdModel.onCallDutyPolicyEscalationRule) === null || _d === void 0 ? void 0 : _d.name) || "No name provided",
            escalationRuleOrder: ((_f = (_e = createdModel.onCallDutyPolicyEscalationRule) === null || _e === void 0 ? void 0 : _e.order) === null || _f === void 0 ? void 0 : _f.toString()) ||
                "No order provided",
            reason: "You are currently on roster for schedule " + scheduleName,
            onCallPolicyViewLink: (await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(createdModel.projectId, createdModel.onCallDutyPolicy.id)).toString(),
        };
        // Notify the current user about being added to the schedule.
        const emailMessage = {
            templateType: EmailTemplateType.UserAddedToOnCallPolicy,
            vars: vars,
            subject: `You have been added to the on-call duty policy ${(_g = createdModel.onCallDutyPolicy) === null || _g === void 0 ? void 0 : _g.name} for schedule ${scheduleName}`,
        };
        const sms = {
            message: `This is a message from OneUptime. You have been added to the on-call duty policy ${(_h = createdModel.onCallDutyPolicy) === null || _h === void 0 ? void 0 : _h.name} for schedule ${scheduleName} and escalation rule ${(_j = createdModel.onCallDutyPolicyEscalationRule) === null || _j === void 0 ? void 0 : _j.name} with order ${(_k = createdModel.onCallDutyPolicyEscalationRule) === null || _k === void 0 ? void 0 : _k.order}. To unsubscribe from this notification, go to User Settings in the OneUptime Dashboard.`,
        };
        const callMessage = {
            data: [
                {
                    sayMessage: `This is a message from OneUptime. You have been added to the on-call duty policy ${(_l = createdModel.onCallDutyPolicy) === null || _l === void 0 ? void 0 : _l.name} for schedule ${scheduleName} and escalation rule ${(_m = createdModel.onCallDutyPolicyEscalationRule) === null || _m === void 0 ? void 0 : _m.name} with order ${(_o = createdModel.onCallDutyPolicyEscalationRule) === null || _o === void 0 ? void 0 : _o.order}. To unsubscribe from this notification, go to User Settings in the OneUptime Dashboard. Goodbye.`,
                },
            ],
        };
        const pushMessage = PushNotificationUtil.createOnCallPolicyAddedNotification({
            policyName: ((_p = createdModel.onCallDutyPolicy) === null || _p === void 0 ? void 0 : _p.name) || "No name provided",
        });
        const eventType = NotificationSettingEventType.SEND_WHEN_USER_IS_ADDED_TO_ON_CALL_POLICY;
        const whatsAppMessage = createWhatsAppMessageFromTemplate({
            eventType,
            templateVariables: {
                on_call_policy_name: ((_q = createdModel.onCallDutyPolicy) === null || _q === void 0 ? void 0 : _q.name) || "No name provided",
                schedule_name: scheduleName,
                on_call_context: `schedule ${scheduleName}`,
                policy_link: vars["onCallPolicyViewLink"] || "",
            },
        });
        await UserNotificationSettingService.sendUserNotification({
            userId: sendEmailToUserId,
            projectId: createdModel.projectId,
            emailEnvelope: emailMessage,
            smsMessage: sms,
            callRequestMessage: callMessage,
            pushNotificationMessage: pushMessage,
            whatsAppMessage,
            eventType,
        });
        // add workspace message.
        const onCallDutyPolicyId = createdModel.onCallDutyPolicy.id;
        const projectId = createdModel.projectId;
        const createdByUserId = createdModel.createdByUserId;
        const onCallSchedule = createdModel.onCallDutyPolicySchedule;
        const onCallDutyPolicyName = ((_r = createdModel.onCallDutyPolicy) === null || _r === void 0 ? void 0 : _r.name) || "";
        if (onCallDutyPolicyId) {
            await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
                onCallDutyPolicyId: onCallDutyPolicyId,
                projectId: projectId,
                onCallDutyPolicyFeedEventType: OnCallDutyPolicyFeedEventType.OnCallDutyScheduleAdded,
                displayColor: Gray500,
                feedInfoInMarkdown: `📅 Added on-call schedule **${(onCallSchedule === null || onCallSchedule === void 0 ? void 0 : onCallSchedule.name) || ""}** from the [On-Call Policy ${onCallDutyPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId, onCallDutyPolicyId)).toString()}) escalation rule **${(_s = createdModel.onCallDutyPolicyEscalationRule) === null || _s === void 0 ? void 0 : _s.name}** with order **${(_t = createdModel.onCallDutyPolicyEscalationRule) === null || _t === void 0 ? void 0 : _t.order}**.`,
                userId: createdByUserId || undefined,
                workspaceNotification: {
                    sendWorkspaceNotification: true,
                    notifyUserId: createdByUserId || undefined,
                },
            });
        }
        return createdItem;
    }
    async onBeforeDelete(deleteBy) {
        var _a, _b, _c, _d;
        const itemsToFetchBeforeDelete = await this.findBy({
            query: deleteBy.query,
            props: {
                isRoot: true,
            },
            select: {
                projectId: true,
                onCallDutyPolicyScheduleId: true,
                onCallDutyPolicySchedule: {
                    name: true,
                    _id: true,
                },
                onCallDutyPolicyEscalationRule: {
                    name: true,
                    _id: true,
                    order: true,
                },
                onCallDutyPolicy: {
                    name: true,
                    _id: true,
                },
            },
            limit: LIMIT_PER_PROJECT,
            skip: 0,
        });
        const deleteByUserId = ((_a = deleteBy.deletedByUser) === null || _a === void 0 ? void 0 : _a.id) || deleteBy.props.userId;
        for (const item of itemsToFetchBeforeDelete) {
            const onCallDutyPolicyId = item.onCallDutyPolicy.id;
            const projectId = item.projectId;
            if (onCallDutyPolicyId && projectId) {
                const onCallDutyPolicyName = ((_b = item.onCallDutyPolicy) === null || _b === void 0 ? void 0 : _b.name) || "No name provided";
                const onCallSchedule = item.onCallDutyPolicySchedule;
                if (!onCallSchedule) {
                    continue;
                }
                await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
                    onCallDutyPolicyId: onCallDutyPolicyId,
                    projectId: projectId,
                    onCallDutyPolicyFeedEventType: OnCallDutyPolicyFeedEventType.OwnerTeamRemoved,
                    displayColor: Red500,
                    feedInfoInMarkdown: `📅 Removed on-call schedule **${onCallSchedule.name}** from the [On-Call Policy ${onCallDutyPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId, onCallDutyPolicyId)).toString()}) escalation rule ${(_c = item.onCallDutyPolicyEscalationRule) === null || _c === void 0 ? void 0 : _c.name} with order ${(_d = item.onCallDutyPolicyEscalationRule) === null || _d === void 0 ? void 0 : _d.order}.`,
                    userId: deleteByUserId || undefined,
                    workspaceNotification: {
                        sendWorkspaceNotification: true,
                        notifyUserId: deleteByUserId || undefined,
                    },
                });
            }
        }
        return {
            deleteBy,
            carryForward: {
                deletedItems: itemsToFetchBeforeDelete,
            },
        };
    }
    async onDeleteSuccess(onDelete, _itemIdsBeforeDelete) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
        const deletedItems = onDelete.carryForward.deletedItems;
        for (const deletedItem of deletedItems) {
            const userOnSchedule = await OnCallDutyPolicyScheduleService.getCurrentUserIdInSchedule(deletedItem.onCallDutyPolicyScheduleId, {
                onCallDutyPolicyId: ((_a = deletedItem.onCallDutyPolicy) === null || _a === void 0 ? void 0 : _a.id) || undefined,
            });
            if (!userOnSchedule) {
                continue;
            }
            const sendEmailToUserId = userOnSchedule;
            if (!sendEmailToUserId) {
                return onDelete;
            }
            const scheduleName = ((_b = deletedItem.onCallDutyPolicySchedule) === null || _b === void 0 ? void 0 : _b.name) || "No name provided";
            const vars = {
                onCallPolicyName: ((_c = deletedItem.onCallDutyPolicy) === null || _c === void 0 ? void 0 : _c.name) || "No name provided",
                escalationRuleName: ((_d = deletedItem.onCallDutyPolicyEscalationRule) === null || _d === void 0 ? void 0 : _d.name) ||
                    "No name provided",
                escalationRuleOrder: ((_f = (_e = deletedItem.onCallDutyPolicyEscalationRule) === null || _e === void 0 ? void 0 : _e.order) === null || _f === void 0 ? void 0 : _f.toString()) ||
                    "No order provided",
                reason: `You have been removed from the on-call duty policy escalation rule for schedule ${scheduleName}.`,
                onCallPolicyViewLink: (await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(deletedItem.projectId, deletedItem.onCallDutyPolicy.id)).toString(),
            };
            // Notify the current user about being removed from the schedule.
            const emailMessage = {
                templateType: EmailTemplateType.UserRemovedFromOnCallPolicy,
                vars: vars,
                subject: `You have been removed from the on-call duty policy ${(_g = deletedItem.onCallDutyPolicy) === null || _g === void 0 ? void 0 : _g.name} for schedule ${scheduleName}`,
            };
            const sms = {
                message: `This is a message from OneUptime. You have been removed from the on-call duty policy ${(_h = deletedItem.onCallDutyPolicy) === null || _h === void 0 ? void 0 : _h.name} for schedule ${scheduleName} and escalation rule ${(_j = deletedItem.onCallDutyPolicyEscalationRule) === null || _j === void 0 ? void 0 : _j.name} with order ${(_k = deletedItem.onCallDutyPolicyEscalationRule) === null || _k === void 0 ? void 0 : _k.order}. To unsubscribe from this notification go to User Settings in OneUptime Dashboard.`,
            };
            const callMessage = {
                data: [
                    {
                        sayMessage: `This is a message from OneUptime. You have been removed from the on-call duty policy ${(_l = deletedItem.onCallDutyPolicy) === null || _l === void 0 ? void 0 : _l.name} for schedule ${scheduleName} and escalation rule ${(_m = deletedItem.onCallDutyPolicyEscalationRule) === null || _m === void 0 ? void 0 : _m.name} with order ${(_o = deletedItem.onCallDutyPolicyEscalationRule) === null || _o === void 0 ? void 0 : _o.order}. To unsubscribe from this notification go to User Settings in OneUptime Dashboard. Good Bye`,
                    },
                ],
            };
            const pushMessage = PushNotificationUtil.createOnCallPolicyRemovedNotification({
                policyName: ((_p = deletedItem.onCallDutyPolicy) === null || _p === void 0 ? void 0 : _p.name) || "No name provided",
            });
            const eventType = NotificationSettingEventType.SEND_WHEN_USER_IS_REMOVED_FROM_ON_CALL_POLICY;
            const whatsAppMessage = createWhatsAppMessageFromTemplate({
                eventType,
                templateVariables: {
                    on_call_policy_name: ((_q = deletedItem.onCallDutyPolicy) === null || _q === void 0 ? void 0 : _q.name) || "No name provided",
                    schedule_name: scheduleName,
                    on_call_context: `schedule ${scheduleName}`,
                    policy_link: vars["onCallPolicyViewLink"] || "",
                },
            });
            await UserNotificationSettingService.sendUserNotification({
                userId: sendEmailToUserId,
                projectId: deletedItem.projectId,
                emailEnvelope: emailMessage,
                smsMessage: sms,
                callRequestMessage: callMessage,
                pushNotificationMessage: pushMessage,
                whatsAppMessage,
                eventType,
            });
        }
        return onDelete;
    }
}
export default new Service();
//# sourceMappingURL=OnCallDutyPolicyEscalationRuleScheduleService.js.map