var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import BadDataException from "../../../../../Types/Exception/BadDataException";
import ObjectID from "../../../../../Types/ObjectID";
import ScheduledMaintenanceService from "../../../../Services/ScheduledMaintenanceService";
import SlackUtil from "../Slack";
import SlackActionType, { PrivateNoteEmojis, PublicNoteEmojis, } from "./ActionTypes";
import Response from "../../../Response";
import ScheduledMaintenancePublicNoteService from "../../../../Services/ScheduledMaintenancePublicNoteService";
import ScheduledMaintenanceInternalNoteService from "../../../../Services/ScheduledMaintenanceInternalNoteService";
import { LIMIT_PER_PROJECT } from "../../../../../Types/Database/LimitMax";
import ScheduledMaintenanceStateService from "../../../../Services/ScheduledMaintenanceStateService";
import logger from "../../../Logger";
import SortOrder from "../../../../../Types/BaseDatabase/SortOrder";
import Monitor from "../../../../../Models/DatabaseModels/Monitor";
import MonitorService from "../../../../Services/MonitorService";
import MonitorStatusService from "../../../../Services/MonitorStatusService";
import Label from "../../../../../Models/DatabaseModels/Label";
import LabelService from "../../../../Services/LabelService";
import ScheduledMaintenance from "../../../../../Models/DatabaseModels/ScheduledMaintenance";
import OneUptimeDate from "../../../../../Types/Date";
import AccessTokenService from "../../../../Services/AccessTokenService";
import CaptureSpan from "../../../Telemetry/CaptureSpan";
import WorkspaceType from "../../../../../Types/Workspace/WorkspaceType";
import WorkspaceUserAuthTokenService from "../../../../Services/WorkspaceUserAuthTokenService";
import WorkspaceNotificationLogService from "../../../../Services/WorkspaceNotificationLogService";
import WorkspaceProjectAuthTokenService from "../../../../Services/WorkspaceProjectAuthTokenService";
export default class SlackScheduledMaintenanceActions {
    static isScheduledMaintenanceAction(data) {
        const { actionType } = data;
        switch (actionType) {
            case SlackActionType.MarkScheduledMaintenanceAsOngoing:
            case SlackActionType.MarkScheduledMaintenanceAsComplete:
            case SlackActionType.ViewAddScheduledMaintenanceNote:
            case SlackActionType.SubmitScheduledMaintenanceNote:
            case SlackActionType.ViewChangeScheduledMaintenanceState:
            case SlackActionType.SubmitChangeScheduledMaintenanceState:
            case SlackActionType.ViewScheduledMaintenance:
            case SlackActionType.NewScheduledMaintenance:
            case SlackActionType.SubmitNewScheduledMaintenance:
                return true;
            default:
                return false;
        }
    }
    static async submitNewScheduledMaintenance(data) {
        var _a;
        const { slackRequest, req, res } = data;
        const { botUserId, userId, projectAuthToken } = slackRequest;
        if (!userId) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid User ID"));
        }
        if (!projectAuthToken) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Project Auth Token"));
        }
        if (!botUserId) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Bot User ID"));
        }
        if (data.action.actionType === SlackActionType.SubmitNewScheduledMaintenance) {
            // We send this early let slack know we're ok. We'll do the rest in the background.
            // if view values is empty, then return error.
            if (!data.slackRequest.viewValues) {
                return Response.sendErrorResponse(req, res, new BadDataException("Invalid View Values"));
            }
            if (!data.slackRequest.viewValues["scheduledMaintenanceTitle"]) {
                return Response.sendErrorResponse(req, res, new BadDataException("Invalid Scheduled Maintenance Title"));
            }
            if (!data.slackRequest.viewValues["scheduledMaintenanceDescription"]) {
                return Response.sendErrorResponse(req, res, new BadDataException("Invalid Scheduled Maintenance Description"));
            }
            // check start date and end date.
            if (!data.slackRequest.viewValues["startDate"]) {
                return Response.sendErrorResponse(req, res, new BadDataException("Invalid Start Date"));
            }
            if (!data.slackRequest.viewValues["endDate"]) {
                return Response.sendErrorResponse(req, res, new BadDataException("Invalid End Date"));
            }
            Response.sendJsonObjectResponse(req, res, {
                response_action: "clear",
            });
            const title = data.slackRequest.viewValues["scheduledMaintenanceTitle"].toString();
            const description = data.slackRequest.viewValues["scheduledMaintenanceDescription"].toString();
            const monitors = (data.slackRequest.viewValues["scheduledMaintenanceMonitors"] || []);
            const monitorStatus = (_a = data.slackRequest.viewValues["monitorStatus"]) === null || _a === void 0 ? void 0 : _a.toString();
            const labels = data.slackRequest.viewValues["labels"] || [];
            const scheduledMaintenanceMonitors = monitors.map((monitor) => {
                return new ObjectID(monitor);
            });
            const scheduledMaintenanceLabels = labels.map((label) => {
                return new ObjectID(label);
            });
            const monitorStatusId = monitorStatus
                ? new ObjectID(monitorStatus)
                : undefined;
            const startDate = OneUptimeDate.fromString(data.slackRequest.viewValues["startDate"].toString());
            const endDate = OneUptimeDate.fromString(data.slackRequest.viewValues["endDate"].toString());
            // make sure start and end date are in the future.
            if (OneUptimeDate.isInTheFuture(startDate) === false) {
                // send slack message to user that start date is in the past.
                const markdownPayload = {
                    _type: "WorkspacePayloadMarkdown",
                    text: `@${slackRequest.slackUsername}, unfortunately you cannot create a scheduled maintenance with start date in the past.`,
                };
                await SlackUtil.sendDirectMessageToUser({
                    messageBlocks: [markdownPayload],
                    authToken: projectAuthToken,
                    workspaceUserId: slackRequest.slackUserId,
                });
                return;
            }
            if (OneUptimeDate.isInTheFuture(endDate) === false) {
                // send slack message to user that end date is in the past.
                const markdownPayload = {
                    _type: "WorkspacePayloadMarkdown",
                    text: `@${slackRequest.slackUsername}, unfortunately you cannot create a scheduled maintenance with end date in the past.`,
                };
                await SlackUtil.sendDirectMessageToUser({
                    messageBlocks: [markdownPayload],
                    authToken: projectAuthToken,
                    workspaceUserId: slackRequest.slackUserId,
                });
                return;
            }
            // make sure end date is after start date.
            if (OneUptimeDate.isAfter(endDate, startDate) === false) {
                // send slack message to user that end date is before start date.
                const markdownPayload = {
                    _type: "WorkspacePayloadMarkdown",
                    text: `@${slackRequest.slackUsername}, unfortunately you cannot create a scheduled maintenance with end date before start date.`,
                };
                await SlackUtil.sendDirectMessageToUser({
                    messageBlocks: [markdownPayload],
                    authToken: projectAuthToken,
                    workspaceUserId: slackRequest.slackUserId,
                });
                return;
            }
            const scheduledMaintenance = new ScheduledMaintenance();
            scheduledMaintenance.title = title;
            scheduledMaintenance.description = description;
            scheduledMaintenance.projectId = slackRequest.projectId;
            if (userId) {
                scheduledMaintenance.createdByUserId = userId;
            }
            scheduledMaintenance.startsAt = startDate;
            scheduledMaintenance.endsAt = endDate;
            if (monitors.length > 0) {
                scheduledMaintenance.monitors = scheduledMaintenanceMonitors.map((monitorId) => {
                    const monitor = new Monitor();
                    monitor.id = monitorId;
                    return monitor;
                });
            }
            if (monitorStatusId) {
                scheduledMaintenance.changeMonitorStatusToId = monitorStatusId;
            }
            if (scheduledMaintenanceLabels.length > 0) {
                scheduledMaintenance.labels = scheduledMaintenanceLabels.map((labelId) => {
                    const label = new Label();
                    label.id = labelId;
                    return label;
                });
            }
            const createdEvent = await ScheduledMaintenanceService.create({
                data: scheduledMaintenance,
                props: {
                    isRoot: true,
                },
            });
            // post a message to Slack after the incident was created.
            const slackChannelId = data.action.actionValue || ""; // this is the channel id where the incident was created.
            if (slackChannelId) {
                await SlackUtil.sendMessage({
                    authToken: projectAuthToken,
                    userId: botUserId,
                    projectId: slackRequest.projectId,
                    workspaceMessagePayload: {
                        _type: "WorkspaceMessagePayload",
                        channelIds: [slackChannelId],
                        channelNames: [],
                        workspaceType: WorkspaceType.Slack,
                        messageBlocks: [
                            {
                                _type: "WorkspacePayloadMarkdown",
                                text: `**Scheduled Event ${createdEvent.scheduledMaintenanceNumberWithPrefix || "#" + createdEvent.scheduledMaintenanceNumber}** created successfully. [View Event](${await ScheduledMaintenanceService.getScheduledMaintenanceLinkInDashboard(slackRequest.projectId, createdEvent.id)})`,
                            },
                        ],
                    },
                });
            }
        }
    }
    static async viewNewScheduledMaintenanceModal(data) {
        const blocks = [];
        // send response to clear the action.
        Response.sendTextResponse(data.req, data.res, "");
        /*
         * show new scheduledMaintenance modal.
         * new scheduledMaintenance modal is :
         * ScheduledMaintenance Title (this can be prefilled with actionValue)
         * ScheduledMaintenance Description
         * Start Date and Time (date picker)
         * End Date and Time (date picker)
         * Monitors (dropdown) (miltiselect)
         * Change Monitor Status to (dropdown) (single select)
         */
        // Labels (dropdown) (multiselect)
        const scheduledMaintenanceTitle = {
            _type: "WorkspaceTextBoxBlock",
            label: "Event Title",
            blockId: "scheduledMaintenanceTitle",
            placeholder: "Scheduled Maintenance Title",
            initialValue: data.action.actionValue || "",
        };
        blocks.push(scheduledMaintenanceTitle);
        const scheduledMaintenanceDescription = {
            _type: "WorkspaceTextAreaBlock",
            label: "Event Description",
            blockId: "scheduledMaintenanceDescription",
            placeholder: "Scheduled Maintenance Description",
        };
        blocks.push(scheduledMaintenanceDescription);
        // start date
        const startDatePicker = {
            _type: "WorkspaceDateTimePickerBlock",
            label: "Start Date and Time",
            blockId: "startDate",
            optional: false,
        };
        blocks.push(startDatePicker);
        // end date
        const endDatePicker = {
            _type: "WorkspaceDateTimePickerBlock",
            label: "End Date and Time",
            blockId: "endDate",
            optional: false,
        };
        blocks.push(endDatePicker);
        const monitorsForProject = await MonitorService.findBy({
            query: {
                projectId: data.slackRequest.projectId,
            },
            select: {
                name: true,
            },
            props: {
                isRoot: true,
            },
            limit: LIMIT_PER_PROJECT,
            skip: 0,
        });
        const monitorDropdownOptions = monitorsForProject.map((monitor) => {
            var _a;
            return {
                label: monitor.name || "",
                value: ((_a = monitor._id) === null || _a === void 0 ? void 0 : _a.toString()) || "",
            };
        });
        const scheduledMaintenanceMonitors = {
            _type: "WorkspaceDropdownBlock",
            label: "Monitors affected",
            blockId: "scheduledMaintenanceMonitors",
            placeholder: "Select Monitors",
            options: monitorDropdownOptions,
            multiSelect: true,
            optional: true,
        };
        if (monitorsForProject.length > 0) {
            blocks.push(scheduledMaintenanceMonitors);
        }
        const monitorStatusForProject = await MonitorStatusService.findBy({
            query: {
                projectId: data.slackRequest.projectId,
            },
            select: {
                name: true,
            },
            props: {
                isRoot: true,
            },
            sort: {
                priority: SortOrder.Ascending,
            },
            limit: LIMIT_PER_PROJECT,
            skip: 0,
        });
        const monitorStatusDropdownOptions = monitorStatusForProject.map((status) => {
            var _a;
            return {
                label: status.name || "",
                value: ((_a = status._id) === null || _a === void 0 ? void 0 : _a.toString()) || "",
            };
        });
        const monitorStatusDropdown = {
            _type: "WorkspaceDropdownBlock",
            label: "Change Monitor Status to",
            description: "Select the status you want to change the monitor to when the event starts.",
            blockId: "monitorStatus",
            placeholder: "Select Monitor Status",
            options: monitorStatusDropdownOptions,
            optional: true,
        };
        if (monitorStatusForProject.length > 0 &&
            monitorDropdownOptions.length > 0) {
            blocks.push(monitorStatusDropdown);
        }
        const labelsForProject = await LabelService.findBy({
            query: {
                projectId: data.slackRequest.projectId,
            },
            select: {
                name: true,
            },
            props: {
                isRoot: true,
            },
            limit: LIMIT_PER_PROJECT,
            skip: 0,
        });
        const labelsDropdownOptions = labelsForProject.map((label) => {
            var _a;
            return {
                label: label.name || "",
                value: ((_a = label._id) === null || _a === void 0 ? void 0 : _a.toString()) || "",
            };
        });
        const labelsDropdown = {
            _type: "WorkspaceDropdownBlock",
            label: "Labels",
            blockId: "labels",
            placeholder: "Select Labels",
            options: labelsDropdownOptions,
            multiSelect: true,
            optional: true,
        };
        if (labelsForProject.length > 0) {
            blocks.push(labelsDropdown);
        }
        const modalBlock = {
            _type: "WorkspaceModalBlock",
            title: "New Scheduled Event",
            submitButtonTitle: "Submit",
            cancelButtonTitle: "Cancel",
            actionId: SlackActionType.SubmitNewScheduledMaintenance,
            actionValue: data.slackRequest.slackChannelId || "",
            blocks: blocks,
        };
        await SlackUtil.showModalToUser({
            authToken: data.slackRequest.projectAuthToken,
            modalBlock: modalBlock,
            triggerId: data.slackRequest.triggerId,
        });
    }
    static async markScheduledMaintenanceAsOngoing(data) {
        var _a, _b;
        const { slackRequest, req, res } = data;
        const { botUserId, userId, projectAuthToken, slackUsername } = slackRequest;
        const { actionValue } = data.action;
        if (!actionValue) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Scheduled Maintenance ID"));
        }
        if (!userId) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid User ID"));
        }
        if (!projectAuthToken) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Project Auth Token"));
        }
        if (!botUserId) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Bot User ID"));
        }
        if (data.action.actionType ===
            SlackActionType.MarkScheduledMaintenanceAsOngoing) {
            const scheduledMaintenanceId = new ObjectID(actionValue);
            // We send this early let slack know we're ok. We'll do the rest in the background.
            Response.sendJsonObjectResponse(req, res, {
                response_action: "clear",
            });
            const isAlreadyOngoing = await ScheduledMaintenanceService.isScheduledMaintenanceOngoing({
                scheduledMaintenanceId: scheduledMaintenanceId,
            });
            if (isAlreadyOngoing) {
                const scheduledMaintenanceNumberResult = await ScheduledMaintenanceService.getScheduledMaintenanceNumber({
                    scheduledMaintenanceId: scheduledMaintenanceId,
                });
                // send a message to the channel visible to user, that the scheduledMaintenance has already been acknowledged.
                const markdwonPayload = {
                    _type: "WorkspacePayloadMarkdown",
                    text: `@${slackUsername}, unfortunately you cannot change the state to ongoing because the **[Scheduled Maintenance ${scheduledMaintenanceNumberResult.numberWithPrefix || "#" + scheduledMaintenanceNumberResult.number}](${await ScheduledMaintenanceService.getScheduledMaintenanceLinkInDashboard(slackRequest.projectId, scheduledMaintenanceId)})** is already in ongoing state.`,
                };
                await SlackUtil.sendDirectMessageToUser({
                    messageBlocks: [markdwonPayload],
                    authToken: projectAuthToken,
                    workspaceUserId: slackRequest.slackUserId,
                });
                return;
            }
            await ScheduledMaintenanceService.markScheduledMaintenanceAsOngoing(scheduledMaintenanceId, userId);
            // Log the button interaction
            if (slackRequest.projectId) {
                try {
                    const logData = {
                        projectId: slackRequest.projectId,
                        workspaceType: WorkspaceType.Slack,
                        userId: userId,
                        buttonAction: "mark_scheduled_maintenance_as_ongoing",
                    };
                    if (slackRequest.slackChannelId) {
                        logData.channelId = slackRequest.slackChannelId;
                    }
                    logData.scheduledMaintenanceId = scheduledMaintenanceId;
                    await WorkspaceNotificationLogService.logButtonPressed(logData, {
                        isRoot: true,
                    });
                }
                catch (err) {
                    logger.error("Error logging button interaction:", {
                        projectId: (_a = slackRequest.projectId) === null || _a === void 0 ? void 0 : _a.toString(),
                        scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
                    });
                    logger.error(err, {
                        projectId: (_b = slackRequest.projectId) === null || _b === void 0 ? void 0 : _b.toString(),
                        scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
                    });
                    // Don't throw the error, just log it so the main flow continues
                }
            }
            // Scheduled Maintenance Feed will send a message to the channel that the scheduledMaintenance has been Ongoing.
            return;
        }
        // invalid action type.
        return Response.sendErrorResponse(req, res, new BadDataException("Invalid Action Type"));
    }
    static async resolveScheduledMaintenance(data) {
        var _a, _b;
        const { slackRequest, req, res } = data;
        const { botUserId, userId, projectAuthToken, slackUsername } = slackRequest;
        const { actionValue } = data.action;
        if (!actionValue) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Scheduled Maintenance ID"));
        }
        if (!userId) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid User ID"));
        }
        if (!projectAuthToken) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Project Auth Token"));
        }
        if (!botUserId) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Bot User ID"));
        }
        if (data.action.actionType ===
            SlackActionType.MarkScheduledMaintenanceAsComplete) {
            const scheduledMaintenanceId = new ObjectID(actionValue);
            // We send this early let slack know we're ok. We'll do the rest in the background.
            Response.sendJsonObjectResponse(req, res, {
                response_action: "clear",
            });
            const isAlreadyResolved = await ScheduledMaintenanceService.isScheduledMaintenanceCompleted({
                scheduledMaintenanceId: scheduledMaintenanceId,
            });
            if (isAlreadyResolved) {
                const scheduledMaintenanceNumberResult = await ScheduledMaintenanceService.getScheduledMaintenanceNumber({
                    scheduledMaintenanceId: scheduledMaintenanceId,
                });
                // send a message to the channel visible to user, that the scheduledMaintenance has already been Resolved.
                const markdwonPayload = {
                    _type: "WorkspacePayloadMarkdown",
                    text: `@${slackUsername}, unfortunately you cannot resolve the **[Scheduled Maintenance ${scheduledMaintenanceNumberResult.numberWithPrefix || "#" + scheduledMaintenanceNumberResult.number}](${await ScheduledMaintenanceService.getScheduledMaintenanceLinkInDashboard(slackRequest.projectId, scheduledMaintenanceId)})**. It has already been resolved.`,
                };
                await SlackUtil.sendDirectMessageToUser({
                    messageBlocks: [markdwonPayload],
                    authToken: projectAuthToken,
                    workspaceUserId: slackRequest.slackUserId,
                });
                return;
            }
            await ScheduledMaintenanceService.markScheduledMaintenanceAsComplete(scheduledMaintenanceId, userId);
            // Log the button interaction
            if (slackRequest.projectId) {
                try {
                    const logData = {
                        projectId: slackRequest.projectId,
                        workspaceType: WorkspaceType.Slack,
                        userId: userId,
                        buttonAction: "mark_scheduled_maintenance_as_complete",
                    };
                    if (slackRequest.slackChannelId) {
                        logData.channelId = slackRequest.slackChannelId;
                    }
                    logData.scheduledMaintenanceId = scheduledMaintenanceId;
                    await WorkspaceNotificationLogService.logButtonPressed(logData, {
                        isRoot: true,
                    });
                }
                catch (err) {
                    logger.error("Error logging button interaction:", {
                        projectId: (_a = slackRequest.projectId) === null || _a === void 0 ? void 0 : _a.toString(),
                        scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
                    });
                    logger.error(err, {
                        projectId: (_b = slackRequest.projectId) === null || _b === void 0 ? void 0 : _b.toString(),
                        scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
                    });
                    // Don't throw the error, just log it so the main flow continues
                }
            }
            return;
        }
        // invalid action type.
        return Response.sendErrorResponse(req, res, new BadDataException("Invalid Action Type"));
    }
    static async viewChangeScheduledMaintenanceState(data) {
        var _a, _b, _c, _d;
        const { req, res } = data;
        const { actionValue } = data.action;
        if (!actionValue) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Scheduled Maintenance ID"));
        }
        // We send this early let slack know we're ok. We'll do the rest in the background.
        Response.sendJsonObjectResponse(req, res, {
            response_action: "clear",
        });
        // const scheduledMaintenanceId: ObjectID = new ObjectID(actionValue);
        // send a modal with a dropdown that says "Public Note" or "Private Note" and a text area to add the note.
        const scheduledMaintenanceStates = await ScheduledMaintenanceStateService.getAllScheduledMaintenanceStates({
            projectId: data.slackRequest.projectId,
            props: {
                isRoot: true,
            },
        });
        logger.debug("Scheduled Maintenance States: ", {
            projectId: (_a = data.slackRequest.projectId) === null || _a === void 0 ? void 0 : _a.toString(),
        });
        logger.debug(scheduledMaintenanceStates, {
            projectId: (_b = data.slackRequest.projectId) === null || _b === void 0 ? void 0 : _b.toString(),
        });
        const dropdownOptions = scheduledMaintenanceStates
            .map((state) => {
            var _a;
            return {
                label: state.name || "",
                value: ((_a = state._id) === null || _a === void 0 ? void 0 : _a.toString()) || "",
            };
        })
            .filter((option) => {
            return option.label !== "" || option.value !== "";
        });
        logger.debug("Dropdown Options: ", {
            projectId: (_c = data.slackRequest.projectId) === null || _c === void 0 ? void 0 : _c.toString(),
        });
        logger.debug(dropdownOptions, {
            projectId: (_d = data.slackRequest.projectId) === null || _d === void 0 ? void 0 : _d.toString(),
        });
        const statePickerDropdown = {
            _type: "WorkspaceDropdownBlock",
            label: "Scheduled Maintenance State",
            blockId: "scheduledMaintenanceState",
            placeholder: "Select Scheduled Maintenance State",
            options: dropdownOptions,
        };
        const modalBlock = {
            _type: "WorkspaceModalBlock",
            title: "Change Event State",
            submitButtonTitle: "Submit",
            cancelButtonTitle: "Cancel",
            actionId: SlackActionType.SubmitChangeScheduledMaintenanceState,
            actionValue: actionValue,
            blocks: [statePickerDropdown],
        };
        await SlackUtil.showModalToUser({
            authToken: data.slackRequest.projectAuthToken,
            modalBlock: modalBlock,
            triggerId: data.slackRequest.triggerId,
        });
    }
    static async submitChangeScheduledMaintenanceState(data) {
        const { req, res } = data;
        const { actionValue } = data.action;
        if (!actionValue) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Scheduled Maintenance ID"));
        }
        // We send this early let slack know we're ok. We'll do the rest in the background.
        Response.sendJsonObjectResponse(req, res, {
            response_action: "clear",
        });
        // const scheduledMaintenanceId: ObjectID = new ObjectID(actionValue);
        // send a modal with a dropdown that says "Public Note" or "Private Note" and a text area to add the note.
        if (!data.slackRequest.viewValues ||
            !data.slackRequest.viewValues["scheduledMaintenanceState"]) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid View Values"));
        }
        const scheduledMaintenanceId = new ObjectID(actionValue);
        const stateString = data.slackRequest.viewValues["scheduledMaintenanceState"].toString();
        const stateId = new ObjectID(stateString);
        await ScheduledMaintenanceService.updateOneById({
            id: scheduledMaintenanceId,
            data: {
                currentScheduledMaintenanceStateId: stateId,
            },
            props: await AccessTokenService.getDatabaseCommonInteractionPropsByUserAndProject({
                userId: data.slackRequest.userId,
                projectId: data.slackRequest.projectId,
            }),
        });
    }
    static async submitScheduledMaintenanceNote(data) {
        const { req, res } = data;
        const { actionValue } = data.action;
        if (!actionValue) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Scheduled Maintenance ID"));
        }
        // const scheduledMaintenanceId: ObjectID = new ObjectID(actionValue);
        // send a modal with a dropdown that says "Public Note" or "Private Note" and a text area to add the note.
        // if view values is empty, then return error.
        if (!data.slackRequest.viewValues) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid View Values"));
        }
        if (!data.slackRequest.viewValues["noteType"]) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Note Type"));
        }
        if (!data.slackRequest.viewValues["note"]) {
            // return error.
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Note"));
        }
        const scheduledMaintenanceId = new ObjectID(actionValue);
        const note = data.slackRequest.viewValues["note"].toString();
        const noteType = data.slackRequest.viewValues["noteType"].toString();
        if (noteType !== "public" && noteType !== "private") {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Note Type"));
        }
        // send empty response.
        Response.sendJsonObjectResponse(req, res, {
            response_action: "clear",
        });
        // if public note then, add a note.
        if (noteType === "public") {
            await ScheduledMaintenancePublicNoteService.addNote({
                scheduledMaintenanceId: scheduledMaintenanceId,
                note: note || "",
                projectId: data.slackRequest.projectId,
                userId: data.slackRequest.userId,
            });
        }
        // if private note then, add a note.
        if (noteType === "private") {
            await ScheduledMaintenanceInternalNoteService.addNote({
                scheduledMaintenanceId: scheduledMaintenanceId,
                note: note || "",
                projectId: data.slackRequest.projectId,
                userId: data.slackRequest.userId,
            });
        }
    }
    static async viewAddScheduledMaintenanceNote(data) {
        const { req, res } = data;
        const { actionValue } = data.action;
        if (!actionValue) {
            return Response.sendErrorResponse(req, res, new BadDataException("Invalid Scheduled Maintenance ID"));
        }
        // We send this early let slack know we're ok. We'll do the rest in the background.
        Response.sendJsonObjectResponse(req, res, {
            response_action: "clear",
        });
        // const scheduledMaintenanceId: ObjectID = new ObjectID(actionValue);
        // send a modal with a dropdown that says "Public Note" or "Private Note" and a text area to add the note.
        const notePickerDropdown = {
            _type: "WorkspaceDropdownBlock",
            label: "Note Type",
            blockId: "noteType",
            placeholder: "Select Note Type",
            options: [
                {
                    label: "Public Note (Will be posted on Status Page)",
                    value: "public",
                },
                {
                    label: "Private Note (Only visible to team members)",
                    value: "private",
                },
            ],
        };
        const noteTextArea = {
            _type: "WorkspaceTextAreaBlock",
            label: "Note",
            blockId: "note",
            placeholder: "Note",
            description: "Please type in plain text or markdown.",
        };
        const modalBlock = {
            _type: "WorkspaceModalBlock",
            title: "Add Note",
            submitButtonTitle: "Submit",
            cancelButtonTitle: "Cancel",
            actionId: SlackActionType.SubmitScheduledMaintenanceNote,
            actionValue: actionValue,
            blocks: [notePickerDropdown, noteTextArea],
        };
        await SlackUtil.showModalToUser({
            authToken: data.slackRequest.projectAuthToken,
            modalBlock: modalBlock,
            triggerId: data.slackRequest.triggerId,
        });
    }
    static async handleScheduledMaintenanceAction(data) {
        // now we should be all set, project is authorized and user is authorized. Lets perform some actions based on the action type.
        const actionType = data.action.actionType;
        if (actionType === SlackActionType.MarkScheduledMaintenanceAsOngoing) {
            return await this.markScheduledMaintenanceAsOngoing(data);
        }
        if (actionType === SlackActionType.MarkScheduledMaintenanceAsComplete) {
            return await this.resolveScheduledMaintenance(data);
        }
        if (actionType === SlackActionType.ViewAddScheduledMaintenanceNote) {
            return await this.viewAddScheduledMaintenanceNote(data);
        }
        if (actionType === SlackActionType.SubmitScheduledMaintenanceNote) {
            return await this.submitScheduledMaintenanceNote(data);
        }
        if (actionType === SlackActionType.ViewChangeScheduledMaintenanceState) {
            return await this.viewChangeScheduledMaintenanceState(data);
        }
        if (actionType === SlackActionType.SubmitChangeScheduledMaintenanceState) {
            return await this.submitChangeScheduledMaintenanceState(data);
        }
        if (actionType === SlackActionType.NewScheduledMaintenance) {
            return await this.viewNewScheduledMaintenanceModal(data);
        }
        if (actionType === SlackActionType.SubmitNewScheduledMaintenance) {
            return await this.submitNewScheduledMaintenance(data);
        }
        if (actionType === SlackActionType.ViewScheduledMaintenance) {
            /*
             * do nothing. This is just a view scheduledMaintenance action.
             * clear response.
             */
            return Response.sendJsonObjectResponse(data.req, data.res, {
                response_action: "clear",
            });
        }
        // invalid action type.
        return Response.sendErrorResponse(data.req, data.res, new BadDataException("Invalid Action Type"));
    }
    static async handleEmojiReaction(data) {
        logger.debug("Handling emoji reaction for Scheduled Maintenance with data:", { channelId: data.channelId });
        logger.debug(data, { channelId: data.channelId });
        const { teamId, reaction, userId, channelId, messageTs } = data;
        // Check if the emoji is a supported private or public note emoji
        const isPrivateNoteEmoji = PrivateNoteEmojis.includes(reaction);
        const isPublicNoteEmoji = PublicNoteEmojis.includes(reaction);
        if (!isPrivateNoteEmoji && !isPublicNoteEmoji) {
            logger.debug(`Emoji "${reaction}" is not a supported note emoji. Ignoring.`, { channelId: data.channelId });
            return;
        }
        // Get the project auth token using the team ID
        const projectAuth = await WorkspaceProjectAuthTokenService.findOneBy({
            query: {
                workspaceProjectId: teamId,
            },
            select: {
                projectId: true,
                authToken: true,
            },
            props: {
                isRoot: true,
            },
        });
        if (!projectAuth || !projectAuth.projectId || !projectAuth.authToken) {
            logger.debug("No project auth found for team ID. Ignoring emoji reaction.", { channelId: data.channelId });
            return;
        }
        const projectId = projectAuth.projectId;
        const authToken = projectAuth.authToken;
        // Find the scheduled maintenance linked to this channel
        const workspaceLog = await WorkspaceNotificationLogService.findOneBy({
            query: {
                channelId: channelId,
                workspaceType: WorkspaceType.Slack,
                projectId: projectId,
            },
            select: {
                scheduledMaintenanceId: true,
            },
            props: {
                isRoot: true,
            },
        });
        if (!workspaceLog || !workspaceLog.scheduledMaintenanceId) {
            logger.debug("No scheduled maintenance found linked to this channel. Ignoring emoji reaction.", {
                projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                channelId: channelId,
            });
            return;
        }
        const scheduledMaintenanceId = workspaceLog.scheduledMaintenanceId;
        // Get the scheduled maintenance number for the confirmation message
        const scheduledMaintenanceNumberResult = await ScheduledMaintenanceService.getScheduledMaintenanceNumber({
            scheduledMaintenanceId: scheduledMaintenanceId,
        });
        // Get the user ID in OneUptime based on Slack user ID
        const userAuth = await WorkspaceUserAuthTokenService.findOneBy({
            query: {
                workspaceUserId: userId,
                workspaceType: WorkspaceType.Slack,
                projectId: projectId,
            },
            select: {
                userId: true,
            },
            props: {
                isRoot: true,
            },
        });
        if (!userAuth || !userAuth.userId) {
            logger.debug("No OneUptime user found for Slack user. Ignoring emoji reaction.", {
                projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
            });
            return;
        }
        const oneUptimeUserId = userAuth.userId;
        // Fetch the message text using the timestamp
        let messageText = null;
        try {
            messageText = await SlackUtil.getMessageByTimestamp({
                authToken: authToken,
                channelId: channelId,
                messageTs: messageTs,
            });
        }
        catch (err) {
            logger.error("Error fetching message text:", {
                projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
            });
            logger.error(err, {
                projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
            });
            return;
        }
        if (!messageText) {
            logger.debug("No message text found. Ignoring emoji reaction.", {
                projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
            });
            return;
        }
        // Create a unique identifier for this Slack message to prevent duplicate notes
        const postedFromSlackMessageId = `${channelId}:${messageTs}`;
        // Save the note based on the emoji type
        let noteType;
        try {
            if (isPrivateNoteEmoji) {
                noteType = "private";
                // Check if a note from this Slack message already exists
                const hasExistingNote = await ScheduledMaintenanceInternalNoteService.hasNoteFromSlackMessage({
                    scheduledMaintenanceId: scheduledMaintenanceId,
                    postedFromSlackMessageId: postedFromSlackMessageId,
                });
                if (hasExistingNote) {
                    logger.debug("Private note from this Slack message already exists. Skipping duplicate.", {
                        projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                        scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
                    });
                    return;
                }
                await ScheduledMaintenanceInternalNoteService.addNote({
                    scheduledMaintenanceId: scheduledMaintenanceId,
                    note: messageText,
                    projectId: projectId,
                    userId: oneUptimeUserId,
                    postedFromSlackMessageId: postedFromSlackMessageId,
                });
                logger.debug("Private note added successfully.", {
                    projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                    scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
                });
            }
            else if (isPublicNoteEmoji) {
                noteType = "public";
                // Check if a note from this Slack message already exists
                const hasExistingNote = await ScheduledMaintenancePublicNoteService.hasNoteFromSlackMessage({
                    scheduledMaintenanceId: scheduledMaintenanceId,
                    postedFromSlackMessageId: postedFromSlackMessageId,
                });
                if (hasExistingNote) {
                    logger.debug("Public note from this Slack message already exists. Skipping duplicate.", {
                        projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                        scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
                    });
                    return;
                }
                await ScheduledMaintenancePublicNoteService.addNote({
                    scheduledMaintenanceId: scheduledMaintenanceId,
                    note: messageText,
                    projectId: projectId,
                    userId: oneUptimeUserId,
                    postedFromSlackMessageId: postedFromSlackMessageId,
                });
                logger.debug("Public note added successfully.", {
                    projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                    scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
                });
            }
            else {
                return;
            }
        }
        catch (err) {
            logger.error("Error saving note:", {
                projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
            });
            logger.error(err, {
                projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
            });
            return;
        }
        // Send confirmation message as a reply to the original message thread
        try {
            const scheduledMaintenanceLink = (await ScheduledMaintenanceService.getScheduledMaintenanceLinkInDashboard(projectId, scheduledMaintenanceId)).toString();
            const confirmationMessage = noteType === "private"
                ? `✅ Message saved as *private note* to <${scheduledMaintenanceLink}|Scheduled Maintenance ${scheduledMaintenanceNumberResult.numberWithPrefix || "#" + scheduledMaintenanceNumberResult.number}>.`
                : `✅ Message saved as *public note* to <${scheduledMaintenanceLink}|Scheduled Maintenance ${scheduledMaintenanceNumberResult.numberWithPrefix || "#" + scheduledMaintenanceNumberResult.number}>. This note will be visible on the status page.`;
            await SlackUtil.sendMessageToThread({
                authToken: authToken,
                channelId: channelId,
                threadTs: messageTs,
                text: confirmationMessage,
            });
            logger.debug("Confirmation message sent successfully.", {
                projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
            });
        }
        catch (err) {
            logger.error("Error sending confirmation message:", {
                projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
            });
            logger.error(err, {
                projectId: projectId === null || projectId === void 0 ? void 0 : projectId.toString(),
                scheduledMaintenanceId: scheduledMaintenanceId === null || scheduledMaintenanceId === void 0 ? void 0 : scheduledMaintenanceId.toString(),
            });
            // Don't throw - note was saved successfully, confirmation is best effort
        }
    }
}
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Boolean)
], SlackScheduledMaintenanceActions, "isScheduledMaintenanceAction", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SlackScheduledMaintenanceActions, "submitNewScheduledMaintenance", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SlackScheduledMaintenanceActions, "viewNewScheduledMaintenanceModal", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SlackScheduledMaintenanceActions, "markScheduledMaintenanceAsOngoing", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SlackScheduledMaintenanceActions, "resolveScheduledMaintenance", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SlackScheduledMaintenanceActions, "viewChangeScheduledMaintenanceState", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SlackScheduledMaintenanceActions, "submitChangeScheduledMaintenanceState", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SlackScheduledMaintenanceActions, "submitScheduledMaintenanceNote", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SlackScheduledMaintenanceActions, "viewAddScheduledMaintenanceNote", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SlackScheduledMaintenanceActions, "handleScheduledMaintenanceAction", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], SlackScheduledMaintenanceActions, "handleEmojiReaction", null);
//# sourceMappingURL=ScheduledMaintenance.js.map