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 Response from "../../../Response";
import MicrosoftTeamsAuthAction from "./Auth";
import { MicrosoftTeamsIncidentEpisodeActionType } from "./ActionTypes";
import logger from "../../../Logger";
import ObjectID from "../../../../../Types/ObjectID";
import IncidentEpisodeService from "../../../../Services/IncidentEpisodeService";
import CaptureSpan from "../../../Telemetry/CaptureSpan";
import IncidentEpisodeInternalNoteService from "../../../../Services/IncidentEpisodeInternalNoteService";
import OnCallDutyPolicyService from "../../../../Services/OnCallDutyPolicyService";
import IncidentStateService from "../../../../Services/IncidentStateService";
import UserNotificationEventType from "../../../../../Types/UserNotification/UserNotificationEventType";
export default class MicrosoftTeamsIncidentEpisodeActions {
    static isIncidentEpisodeAction(data) {
        return (data.actionType.includes("IncidentEpisode") ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.AckIncidentEpisode ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.ResolveIncidentEpisode ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.ViewIncidentEpisode ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.IncidentEpisodeCreated ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.IncidentEpisodeStateChanged ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.ViewAddIncidentEpisodeNote ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.SubmitIncidentEpisodeNote ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.ViewExecuteIncidentEpisodeOnCallPolicy ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.SubmitExecuteIncidentEpisodeOnCallPolicy ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.ViewChangeIncidentEpisodeState ||
            data.actionType ===
                MicrosoftTeamsIncidentEpisodeActionType.SubmitChangeIncidentEpisodeState);
    }
    static async handleIncidentEpisodeAction(data) {
        const { teamsRequest, action } = data;
        logger.debug("Handling Microsoft Teams incident episode action:");
        logger.debug(action);
        try {
            switch (action.actionType) {
                case MicrosoftTeamsIncidentEpisodeActionType.AckIncidentEpisode:
                    await this.acknowledgeIncidentEpisode({
                        teamsRequest,
                        action,
                    });
                    break;
                case MicrosoftTeamsIncidentEpisodeActionType.ResolveIncidentEpisode:
                    await this.resolveIncidentEpisode({
                        teamsRequest,
                        action,
                    });
                    break;
                case MicrosoftTeamsIncidentEpisodeActionType.ViewIncidentEpisode:
                    // This is handled by opening the URL directly
                    break;
                default:
                    logger.debug("Unhandled incident episode action: " + action.actionType);
                    break;
            }
        }
        catch (error) {
            logger.error("Error handling Microsoft Teams incident episode action:");
            logger.error(error);
        }
        Response.sendTextResponse(data.req, data.res, "");
    }
    static async acknowledgeIncidentEpisode(data) {
        var _a;
        const episodeId = data.action.actionValue || "";
        if (!episodeId) {
            logger.error("No episode ID provided for acknowledge action");
            return;
        }
        logger.debug("Acknowledging incident episode: " + episodeId);
        try {
            const episode = await IncidentEpisodeService.findOneBy({
                query: {
                    _id: episodeId,
                    projectId: data.teamsRequest.projectId,
                },
                select: {
                    _id: true,
                    projectId: true,
                    currentIncidentState: {
                        _id: true,
                        name: true,
                        isAcknowledgedState: true,
                    },
                },
                props: {
                    isRoot: true,
                },
            });
            if (!episode) {
                logger.error("Incident episode not found: " + episodeId);
                return;
            }
            if ((_a = episode.currentIncidentState) === null || _a === void 0 ? void 0 : _a.isAcknowledgedState) {
                logger.debug("Incident episode is already acknowledged");
                return;
            }
            const oneUptimeUserId = await MicrosoftTeamsAuthAction.getOneUptimeUserIdFromTeamsUserId({
                teamsUserId: data.teamsRequest.userId || "",
                projectId: data.teamsRequest.projectId,
            });
            await IncidentEpisodeService.acknowledgeEpisode(new ObjectID(episodeId), oneUptimeUserId);
            logger.debug("Incident episode acknowledged successfully");
        }
        catch (error) {
            logger.error("Error acknowledging incident episode:");
            logger.error(error);
        }
    }
    static async resolveIncidentEpisode(data) {
        var _a;
        const episodeId = data.action.actionValue || "";
        if (!episodeId) {
            logger.error("No episode ID provided for resolve action");
            return;
        }
        logger.debug("Resolving incident episode: " + episodeId);
        try {
            const episode = await IncidentEpisodeService.findOneBy({
                query: {
                    _id: episodeId,
                    projectId: data.teamsRequest.projectId,
                },
                select: {
                    _id: true,
                    projectId: true,
                    currentIncidentState: {
                        _id: true,
                        name: true,
                        isResolvedState: true,
                    },
                },
                props: {
                    isRoot: true,
                },
            });
            if (!episode) {
                logger.error("Incident episode not found: " + episodeId);
                return;
            }
            if ((_a = episode.currentIncidentState) === null || _a === void 0 ? void 0 : _a.isResolvedState) {
                logger.debug("Incident episode is already resolved");
                return;
            }
            const oneUptimeUserId = await MicrosoftTeamsAuthAction.getOneUptimeUserIdFromTeamsUserId({
                teamsUserId: data.teamsRequest.userId || "",
                projectId: data.teamsRequest.projectId,
            });
            await IncidentEpisodeService.resolveEpisode(new ObjectID(episodeId), oneUptimeUserId);
            logger.debug("Incident episode resolved successfully");
        }
        catch (error) {
            logger.error("Error resolving incident episode:");
            logger.error(error);
        }
    }
    static async handleBotIncidentEpisodeAction(data) {
        var _a, _b;
        const { actionType, actionValue, value, projectId, oneUptimeUserId, turnContext, } = data;
        if (actionType === MicrosoftTeamsIncidentEpisodeActionType.AckIncidentEpisode) {
            if (!actionValue) {
                await turnContext.sendActivity("Unable to acknowledge: missing incident episode id.");
                return;
            }
            await IncidentEpisodeService.acknowledgeEpisode(new ObjectID(actionValue), oneUptimeUserId);
            await turnContext.sendActivity("Incident episode acknowledged.");
            return;
        }
        if (actionType ===
            MicrosoftTeamsIncidentEpisodeActionType.ResolveIncidentEpisode) {
            if (!actionValue) {
                await turnContext.sendActivity("Unable to resolve: missing incident episode id.");
                return;
            }
            await IncidentEpisodeService.resolveEpisode(new ObjectID(actionValue), oneUptimeUserId);
            await turnContext.sendActivity("Incident episode resolved.");
            return;
        }
        if (actionType === MicrosoftTeamsIncidentEpisodeActionType.ViewIncidentEpisode) {
            if (!actionValue) {
                await turnContext.sendActivity("Unable to view incident episode: missing episode id.");
                return;
            }
            const episode = await IncidentEpisodeService.findOneBy({
                query: {
                    _id: actionValue,
                    projectId: projectId,
                },
                select: {
                    _id: true,
                    title: true,
                    description: true,
                    currentIncidentState: {
                        name: true,
                    },
                    incidentSeverity: {
                        name: true,
                    },
                    createdAt: true,
                    incidentCount: true,
                },
                props: {
                    isRoot: true,
                },
            });
            if (!episode) {
                await turnContext.sendActivity("Incident episode not found.");
                return;
            }
            const message = `**Incident Episode Details**\n\n**Title:** ${episode.title}\n**Description:** ${episode.description || "No description"}\n**State:** ${((_a = episode.currentIncidentState) === null || _a === void 0 ? void 0 : _a.name) || "Unknown"}\n**Severity:** ${((_b = episode.incidentSeverity) === null || _b === void 0 ? void 0 : _b.name) || "Unknown"}\n**Incident Count:** ${episode.incidentCount || 0}\n**Created At:** ${episode.createdAt ? new Date(episode.createdAt).toLocaleString() : "Unknown"}`;
            await turnContext.sendActivity(message);
            return;
        }
        if (actionType ===
            MicrosoftTeamsIncidentEpisodeActionType.ViewAddIncidentEpisodeNote) {
            if (!actionValue) {
                await turnContext.sendActivity("Unable to add note: missing episode id.");
                return;
            }
            // Send the input card
            const card = this.buildAddIncidentEpisodeNoteCard(actionValue);
            await turnContext.sendActivity({
                attachments: [
                    {
                        contentType: "application/vnd.microsoft.card.adaptive",
                        content: card,
                    },
                ],
            });
            return;
        }
        if (actionType ===
            MicrosoftTeamsIncidentEpisodeActionType.SubmitIncidentEpisodeNote) {
            if (!actionValue) {
                await turnContext.sendActivity("Unable to add note: missing episode id.");
                return;
            }
            // Check if form data is provided
            const note = value["note"];
            if (note) {
                // Submit the note
                const episodeId = new ObjectID(actionValue);
                await IncidentEpisodeInternalNoteService.addNote({
                    incidentEpisodeId: episodeId,
                    note: note.toString(),
                    projectId: projectId,
                    userId: oneUptimeUserId,
                });
                await turnContext.sendActivity("Note added successfully.");
                // Hide the form card by deleting it
                if (turnContext.activity.replyToId) {
                    await turnContext.deleteActivity(turnContext.activity.replyToId);
                }
                return;
            }
            await turnContext.sendActivity("Unable to add note: missing note data.");
            return;
        }
        if (actionType ===
            MicrosoftTeamsIncidentEpisodeActionType.ViewExecuteIncidentEpisodeOnCallPolicy) {
            if (!actionValue) {
                await turnContext.sendActivity("Unable to execute on-call policy: missing episode id.");
                return;
            }
            // Send the input card
            const card = await this.buildExecuteIncidentEpisodeOnCallPolicyCard(actionValue, projectId);
            if (!card) {
                await turnContext.sendActivity("No on-call policies have been configured for this project yet. Please add an on-call policy in the OneUptime Dashboard under On-Call Duty > Policies to use this feature.");
                return;
            }
            await turnContext.sendActivity({
                attachments: [
                    {
                        contentType: "application/vnd.microsoft.card.adaptive",
                        content: card,
                    },
                ],
            });
            return;
        }
        if (actionType ===
            MicrosoftTeamsIncidentEpisodeActionType.SubmitExecuteIncidentEpisodeOnCallPolicy) {
            if (!actionValue) {
                await turnContext.sendActivity("Unable to execute on-call policy: missing episode id.");
                return;
            }
            // Check if form data is provided
            const onCallPolicyId = value["onCallPolicy"];
            if (onCallPolicyId) {
                // Execute the policy
                const episodeId = new ObjectID(actionValue);
                await OnCallDutyPolicyService.executePolicy(new ObjectID(onCallPolicyId.toString()), {
                    triggeredByIncidentEpisodeId: episodeId,
                    userNotificationEventType: UserNotificationEventType.IncidentEpisodeCreated,
                });
                await turnContext.sendActivity("On-call policy executed successfully.");
                // Hide the form card by deleting it
                if (turnContext.activity.replyToId) {
                    await turnContext.deleteActivity(turnContext.activity.replyToId);
                }
                return;
            }
            await turnContext.sendActivity("Unable to execute on-call policy: missing policy id.");
            return;
        }
        if (actionType ===
            MicrosoftTeamsIncidentEpisodeActionType.ViewChangeIncidentEpisodeState) {
            if (!actionValue) {
                await turnContext.sendActivity("Unable to change episode state: missing episode id.");
                return;
            }
            // Send the input card
            const card = await this.buildChangeIncidentEpisodeStateCard(actionValue, projectId);
            await turnContext.sendActivity({
                attachments: [
                    {
                        contentType: "application/vnd.microsoft.card.adaptive",
                        content: card,
                    },
                ],
            });
            return;
        }
        if (actionType ===
            MicrosoftTeamsIncidentEpisodeActionType.SubmitChangeIncidentEpisodeState) {
            if (!actionValue) {
                await turnContext.sendActivity("Unable to change episode state: missing episode id.");
                return;
            }
            // Check if form data is provided
            const incidentStateId = value["incidentState"];
            if (incidentStateId) {
                // Update the state
                const episodeId = new ObjectID(actionValue);
                await IncidentEpisodeService.changeEpisodeState({
                    projectId: projectId,
                    episodeId: episodeId,
                    incidentStateId: new ObjectID(incidentStateId.toString()),
                    notifyOwners: true,
                    rootCause: "State changed via Microsoft Teams.",
                    props: {
                        isRoot: true,
                    },
                });
                await turnContext.sendActivity("Incident episode state changed successfully.");
                // Hide the form card by deleting it
                if (turnContext.activity.replyToId) {
                    await turnContext.deleteActivity(turnContext.activity.replyToId);
                }
                return;
            }
            await turnContext.sendActivity("Unable to change episode state: missing state id.");
            return;
        }
        // Default fallback for unimplemented actions
        await turnContext.sendActivity("Sorry, but the action " +
            actionType +
            " you requested is not implemented yet.");
    }
    static buildAddIncidentEpisodeNoteCard(episodeId) {
        return {
            type: "AdaptiveCard",
            $schema: "http://adaptivecards.io/schemas/adaptive-card.json",
            version: "1.5",
            body: [
                {
                    type: "TextBlock",
                    text: "Add Incident Episode Note",
                    size: "Large",
                    weight: "Bolder",
                },
                {
                    type: "Input.Text",
                    id: "note",
                    label: "Note",
                    isMultiline: true,
                    placeholder: "Please type in plain text or markdown.",
                },
            ],
            actions: [
                {
                    type: "Action.Submit",
                    title: "Submit",
                    data: {
                        action: MicrosoftTeamsIncidentEpisodeActionType.SubmitIncidentEpisodeNote,
                        actionValue: episodeId,
                    },
                },
            ],
        };
    }
    static async buildExecuteIncidentEpisodeOnCallPolicyCard(episodeId, projectId) {
        const onCallPolicies = await OnCallDutyPolicyService.findBy({
            query: {
                projectId: projectId,
            },
            select: {
                name: true,
                _id: true,
            },
            props: {
                isRoot: true,
            },
            limit: 50,
            skip: 0,
        });
        const choices = onCallPolicies
            .map((policy) => {
            var _a;
            return {
                title: policy.name || "",
                value: ((_a = policy._id) === null || _a === void 0 ? void 0 : _a.toString()) || "",
            };
        })
            .filter((choice) => {
            return choice.title && choice.value;
        });
        if (choices.length === 0) {
            return null;
        }
        return {
            type: "AdaptiveCard",
            $schema: "http://adaptivecards.io/schemas/adaptive-card.json",
            version: "1.5",
            body: [
                {
                    type: "TextBlock",
                    text: "Execute On-Call Policy",
                    size: "Large",
                    weight: "Bolder",
                },
                {
                    type: "Input.ChoiceSet",
                    id: "onCallPolicy",
                    label: "On-Call Policy",
                    style: "compact",
                    choices: choices,
                },
            ],
            actions: [
                {
                    type: "Action.Submit",
                    title: "Execute",
                    data: {
                        action: MicrosoftTeamsIncidentEpisodeActionType.SubmitExecuteIncidentEpisodeOnCallPolicy,
                        actionValue: episodeId,
                    },
                },
            ],
        };
    }
    static async buildChangeIncidentEpisodeStateCard(episodeId, projectId) {
        const incidentStates = await IncidentStateService.getAllIncidentStates({
            projectId: projectId,
            props: {
                isRoot: true,
            },
        });
        const choices = incidentStates
            .map((state) => {
            var _a;
            return {
                title: state.name || "",
                value: ((_a = state._id) === null || _a === void 0 ? void 0 : _a.toString()) || "",
            };
        })
            .filter((choice) => {
            return choice.title && choice.value;
        });
        return {
            type: "AdaptiveCard",
            $schema: "http://adaptivecards.io/schemas/adaptive-card.json",
            version: "1.5",
            body: [
                {
                    type: "TextBlock",
                    text: "Change Incident Episode State",
                    size: "Large",
                    weight: "Bolder",
                },
                {
                    type: "Input.ChoiceSet",
                    id: "incidentState",
                    label: "Incident State",
                    style: "compact",
                    choices: choices,
                },
            ],
            actions: [
                {
                    type: "Action.Submit",
                    title: "Change",
                    data: {
                        action: MicrosoftTeamsIncidentEpisodeActionType.SubmitChangeIncidentEpisodeState,
                        actionValue: episodeId,
                    },
                },
            ],
        };
    }
}
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Boolean)
], MicrosoftTeamsIncidentEpisodeActions, "isIncidentEpisodeAction", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], MicrosoftTeamsIncidentEpisodeActions, "handleIncidentEpisodeAction", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], MicrosoftTeamsIncidentEpisodeActions, "acknowledgeIncidentEpisode", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], MicrosoftTeamsIncidentEpisodeActions, "resolveIncidentEpisode", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], MicrosoftTeamsIncidentEpisodeActions, "handleBotIncidentEpisodeAction", null);
//# sourceMappingURL=IncidentEpisode.js.map