import BadDataException from "../../Types/Exception/BadDataException";
import DatabaseService from "./DatabaseService";
import Model from "../../Models/DatabaseModels/OnCallDutyPolicyEscalationRuleTeam";
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 TeamMemberService from "./TeamMemberService";
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";
import OnCallDutyPolicyTimeLogService from "./OnCallDutyPolicyTimeLogService";
import OneUptimeDate from "../../Types/Date";
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;
        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,
                teamId: true,
                team: {
                    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.teamId) {
            throw new BadDataException("Created item does not have a teamId");
        }
        // send notification to the new current user.
        const usersInTeam = await TeamMemberService.getUsersInTeam(createdModel.teamId);
        for (const user of usersInTeam) {
            const temaName = ((_a = createdModel.team) === null || _a === void 0 ? void 0 : _a.name) || "No name provided";
            const sendEmailToUserId = user === null || user === void 0 ? void 0 : user.id;
            if (!sendEmailToUserId) {
                return createdItem;
            }
            if (!createdModel) {
                return createdItem;
            }
            const vars = {
                onCallPolicyName: ((_b = createdModel.onCallDutyPolicy) === null || _b === void 0 ? void 0 : _b.name) || "No name provided",
                escalationRuleName: ((_c = createdModel.onCallDutyPolicyEscalationRule) === null || _c === void 0 ? void 0 : _c.name) ||
                    "No name provided",
                escalationRuleOrder: ((_e = (_d = createdModel.onCallDutyPolicyEscalationRule) === null || _d === void 0 ? void 0 : _d.order) === null || _e === void 0 ? void 0 : _e.toString()) ||
                    "No order provided",
                reason: "You have been added to the on-call duty policy escalation rule because you are a member of the team " +
                    temaName,
                onCallPolicyViewLink: (await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(createdModel.projectId, createdModel.onCallDutyPolicy.id)).toString(),
            };
            // current user changed, send alert the new current user.
            const emailMessage = {
                templateType: EmailTemplateType.UserAddedToOnCallPolicy,
                vars: vars,
                subject: `You have been added to the on-call duty policy ${(_f = createdModel.onCallDutyPolicy) === null || _f === void 0 ? void 0 : _f.name} for team ${temaName}`,
            };
            const sms = {
                message: `This is a message from OneUptime. You have been added to the on-call duty policy ${(_g = createdModel.onCallDutyPolicy) === null || _g === void 0 ? void 0 : _g.name} for team ${temaName} and escalation rule ${(_h = createdModel.onCallDutyPolicyEscalationRule) === null || _h === void 0 ? void 0 : _h.name} with order ${(_j = createdModel.onCallDutyPolicyEscalationRule) === null || _j === void 0 ? void 0 : _j.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 added to the on-call duty policy ${(_k = createdModel.onCallDutyPolicy) === null || _k === void 0 ? void 0 : _k.name} for team ${temaName} and escalation rule ${(_l = createdModel.onCallDutyPolicyEscalationRule) === null || _l === void 0 ? void 0 : _l.name} with order ${(_m = createdModel.onCallDutyPolicyEscalationRule) === null || _m === void 0 ? void 0 : _m.order}. To unsubscribe from this notification go to User Settings in OneUptime Dashboard. Good Bye`,
                    },
                ],
            };
            const pushMessage = PushNotificationUtil.createOnCallPolicyAddedNotification({
                policyName: ((_o = createdModel.onCallDutyPolicy) === null || _o === void 0 ? void 0 : _o.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: ((_p = createdModel.onCallDutyPolicy) === null || _p === void 0 ? void 0 : _p.name) || "No name provided",
                    on_call_context: `team ${temaName}`,
                    policy_link: vars["onCallPolicyViewLink"] || "",
                },
            });
            await UserNotificationSettingService.sendUserNotification({
                userId: sendEmailToUserId,
                projectId: createdModel.projectId,
                emailEnvelope: emailMessage,
                smsMessage: sms,
                callRequestMessage: callMessage,
                pushNotificationMessage: pushMessage,
                whatsAppMessage,
                eventType,
            });
            // add start log
            OnCallDutyPolicyTimeLogService.startTimeLogForUser({
                userId: sendEmailToUserId,
                onCallDutyPolicyId: createdModel.onCallDutyPolicy.id,
                onCallDutyPolicyEscalationRuleId: createdModel.onCallDutyPolicyEscalationRule.id,
                projectId: createdModel.projectId,
                teamId: createdModel.teamId,
                startsAt: new Date(),
            });
        }
        // add workspace message.
        const onCallDutyPolicyId = createdModel.onCallDutyPolicy.id;
        const projectId = createdModel.projectId;
        const createdByUserId = createdModel.createdByUserId;
        const team = createdModel.team;
        const onCallDutyPolicyName = ((_q = createdModel.onCallDutyPolicy) === null || _q === void 0 ? void 0 : _q.name) || "";
        if (onCallDutyPolicyId) {
            await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
                onCallDutyPolicyId: onCallDutyPolicyId,
                projectId: projectId,
                onCallDutyPolicyFeedEventType: OnCallDutyPolicyFeedEventType.TeamAdded,
                displayColor: Gray500,
                feedInfoInMarkdown: `👨🏻‍👩🏻‍👦🏻 Added team **${(team === null || team === void 0 ? void 0 : team.name) || ""}** from the [On-Call Policy ${onCallDutyPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId, onCallDutyPolicyId)).toString()}) escalation rule **${(_r = createdModel.onCallDutyPolicyEscalationRule) === null || _r === void 0 ? void 0 : _r.name}** with order **${(_s = createdModel.onCallDutyPolicyEscalationRule) === null || _s === void 0 ? void 0 : _s.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,
                teamId: true,
                team: {
                    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 team = item.team;
                if (!team) {
                    continue;
                }
                await OnCallDutyPolicyFeedService.createOnCallDutyPolicyFeedItem({
                    onCallDutyPolicyId: onCallDutyPolicyId,
                    projectId: projectId,
                    onCallDutyPolicyFeedEventType: OnCallDutyPolicyFeedEventType.OwnerTeamRemoved,
                    displayColor: Red500,
                    feedInfoInMarkdown: `👨🏻‍👩🏻‍👦🏻 Removed team **${team.name}** from the [On-Call Policy ${onCallDutyPolicyName}](${(await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(projectId, onCallDutyPolicyId)).toString()}) and 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;
        const deletedItems = onDelete.carryForward.deletedItems;
        for (const deletedItem of deletedItems) {
            const usersInTeam = await TeamMemberService.getUsersInTeam(deletedItem.teamId);
            for (const user of usersInTeam) {
                const sendEmailToUserId = user === null || user === void 0 ? void 0 : user.id;
                if (!sendEmailToUserId) {
                    return onDelete;
                }
                const teamName = ((_a = deletedItem.team) === null || _a === void 0 ? void 0 : _a.name) || "No name provided";
                const vars = {
                    onCallPolicyName: ((_b = deletedItem.onCallDutyPolicy) === null || _b === void 0 ? void 0 : _b.name) || "No name provided",
                    escalationRuleName: ((_c = deletedItem.onCallDutyPolicyEscalationRule) === null || _c === void 0 ? void 0 : _c.name) ||
                        "No name provided",
                    escalationRuleOrder: ((_e = (_d = deletedItem.onCallDutyPolicyEscalationRule) === null || _d === void 0 ? void 0 : _d.order) === null || _e === void 0 ? void 0 : _e.toString()) ||
                        "No order provided",
                    reason: `You have been removed from the on-call duty policy escalation rule for team ${teamName}.`,
                    onCallPolicyViewLink: (await OnCallDutyPolicyService.getOnCallDutyPolicyLinkInDashboard(deletedItem.projectId, deletedItem.onCallDutyPolicy.id)).toString(),
                };
                // current user changed, send alert the new current user.
                const emailMessage = {
                    templateType: EmailTemplateType.UserRemovedFromOnCallPolicy,
                    vars: vars,
                    subject: `You have been removed from the on-call duty policy ${(_f = deletedItem.onCallDutyPolicy) === null || _f === void 0 ? void 0 : _f.name} for team ${teamName}`,
                };
                const sms = {
                    message: `This is a message from OneUptime. You have been removed from the on-call duty policy ${(_g = deletedItem.onCallDutyPolicy) === null || _g === void 0 ? void 0 : _g.name} for team ${teamName} and escalation rule ${(_h = deletedItem.onCallDutyPolicyEscalationRule) === null || _h === void 0 ? void 0 : _h.name} with order ${(_j = deletedItem.onCallDutyPolicyEscalationRule) === null || _j === void 0 ? void 0 : _j.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 ${(_k = deletedItem.onCallDutyPolicy) === null || _k === void 0 ? void 0 : _k.name} for team ${teamName} and escalation rule ${(_l = deletedItem.onCallDutyPolicyEscalationRule) === null || _l === void 0 ? void 0 : _l.name} with order ${(_m = deletedItem.onCallDutyPolicyEscalationRule) === null || _m === void 0 ? void 0 : _m.order}. To unsubscribe from this notification go to User Settings in OneUptime Dashboard. Good Bye`,
                        },
                    ],
                };
                const pushMessage = PushNotificationUtil.createOnCallPolicyRemovedNotification({
                    policyName: ((_o = deletedItem.onCallDutyPolicy) === null || _o === void 0 ? void 0 : _o.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: ((_p = deletedItem.onCallDutyPolicy) === null || _p === void 0 ? void 0 : _p.name) || "No name provided",
                        on_call_context: `team ${teamName}`,
                        policy_link: vars["onCallPolicyViewLink"] || "",
                    },
                });
                UserNotificationSettingService.sendUserNotification({
                    userId: sendEmailToUserId,
                    projectId: deletedItem.projectId,
                    emailEnvelope: emailMessage,
                    smsMessage: sms,
                    callRequestMessage: callMessage,
                    pushNotificationMessage: pushMessage,
                    whatsAppMessage,
                    eventType,
                });
                // end time log
                await OnCallDutyPolicyTimeLogService.endTimeLogForUser({
                    userId: sendEmailToUserId,
                    onCallDutyPolicyId: deletedItem.onCallDutyPolicy.id,
                    onCallDutyPolicyEscalationRuleId: deletedItem.onCallDutyPolicyEscalationRule.id,
                    projectId: deletedItem.projectId,
                    teamId: deletedItem.teamId,
                    endsAt: OneUptimeDate.getCurrentDate(),
                });
            }
        }
        return onDelete;
    }
}
export default new Service();
//# sourceMappingURL=OnCallDutyPolicyEscalationRuleTeamService.js.map