import DatabaseConfig from "../DatabaseConfig";
import NotificationMiddleware from "../Middleware/NotificationMiddleware";
import UserOnCallLogTimelineService from "../Services/UserOnCallLogTimelineService";
import Response from "../Utils/Response";
import BaseAPI from "./BaseAPI";
import { AppApiRoute, DashboardRoute } from "../../ServiceRoute";
import URL from "../../Types/API/URL";
import OneUptimeDate from "../../Types/Date";
import BadDataException from "../../Types/Exception/BadDataException";
import ObjectID from "../../Types/ObjectID";
import UserNotificationStatus from "../../Types/UserNotification/UserNotificationStatus";
import UserOnCallLogTimeline from "../../Models/DatabaseModels/UserOnCallLogTimeline";
import Route from "../../Types/API/Route";
export default class UserNotificationLogTimelineAPI extends BaseAPI {
    constructor() {
        var _a, _b, _c;
        super(UserOnCallLogTimeline, UserOnCallLogTimelineService);
        this.router.post(`${(_a = new this.entityType()
            .getCrudApiPath()) === null || _a === void 0 ? void 0 : _a.toString()}/call/gather-input/:itemId`, NotificationMiddleware.isValidCallNotificationRequest, async (req, res, next) => {
            try {
                req = req;
                if (!req.params["itemId"]) {
                    return Response.sendErrorResponse(req, res, new BadDataException("Invalid item ID"));
                }
                const token = req.callTokenData;
                const itemId = new ObjectID(req.params["itemId"]);
                const timelineItem = await this.service.findOneById({
                    id: itemId,
                    select: {
                        _id: true,
                        projectId: true,
                        triggeredByIncidentId: true,
                        triggeredByAlertId: true,
                    },
                    props: {
                        isRoot: true,
                    },
                });
                if (!timelineItem) {
                    return Response.sendErrorResponse(req, res, new BadDataException("Invalid item Id"));
                }
                // check digits.
                if (req.body["Digits"] === "1") {
                    // then ack incident
                    await this.service.updateOneById({
                        id: itemId,
                        data: {
                            acknowledgedAt: OneUptimeDate.getCurrentDate(),
                            isAcknowledged: true,
                            status: UserNotificationStatus.Acknowledged,
                            statusMessage: "Notification Acknowledged",
                        },
                        props: {
                            isRoot: true,
                        },
                    });
                }
                return NotificationMiddleware.sendResponse(req, res, token);
            }
            catch (error) {
                return next(error);
            }
        });
        /*
         * We have this ack page to show the user a confirmation page before acknowledging the notification.
         * this is because email clients automatically make a get request to the url in the email and ack the notification automatically which is not what we want.
         * so we need to create this page for the user to confirm that they want to acknowledge the notification.
         */
        this.router.get(`${(_b = new this.entityType()
            .getCrudApiPath()) === null || _b === void 0 ? void 0 : _b.toString()}/acknowledge-page/:itemId`, async (req, res, next) => {
            var _a, _b, _c, _d;
            try {
                req = req;
                if (!req.params["itemId"]) {
                    return Response.sendErrorResponse(req, res, new BadDataException("Item ID is required"));
                }
                const itemId = new ObjectID(req.params["itemId"]);
                const timelineItem = await this.service.findOneById({
                    id: itemId,
                    select: {
                        _id: true,
                        projectId: true,
                        triggeredByIncidentId: true,
                        triggeredByIncident: {
                            title: true,
                            description: true,
                        },
                        triggeredByAlertId: true,
                        triggeredByAlert: {
                            title: true,
                            description: true,
                        },
                        triggeredByAlertEpisodeId: true,
                        triggeredByAlertEpisode: {
                            title: true,
                            description: true,
                        },
                        triggeredByIncidentEpisodeId: true,
                        triggeredByIncidentEpisode: {
                            title: true,
                            description: true,
                        },
                    },
                    props: {
                        isRoot: true,
                    },
                });
                if (!timelineItem) {
                    return Response.sendErrorResponse(req, res, new BadDataException("Invalid item Id"));
                }
                const notificationType = timelineItem.triggeredByIncidentId
                    ? "Incident"
                    : timelineItem.triggeredByIncidentEpisodeId
                        ? "Incident Episode"
                        : timelineItem.triggeredByAlertEpisodeId
                            ? "Alert Episode"
                            : "Alert";
                const notificationTitle = ((_a = timelineItem.triggeredByIncident) === null || _a === void 0 ? void 0 : _a.title) ||
                    ((_b = timelineItem.triggeredByIncidentEpisode) === null || _b === void 0 ? void 0 : _b.title) ||
                    ((_c = timelineItem.triggeredByAlertEpisode) === null || _c === void 0 ? void 0 : _c.title) ||
                    ((_d = timelineItem.triggeredByAlert) === null || _d === void 0 ? void 0 : _d.title) ||
                    "";
                const host = await DatabaseConfig.getHost();
                const httpProtocol = await DatabaseConfig.getHttpProtocol();
                return Response.render(req, res, "/usr/src/Common/Server/Views/AcknowledgeUserOnCallNotification.ejs", {
                    title: `Acknowledge ${notificationType} - ${notificationTitle}`,
                    message: `Do you want to acknowledge this ${notificationType}?`,
                    acknowledgeText: `Acknowledge ${notificationType}`,
                    acknowledgeUrl: new URL(httpProtocol, host, new Route(AppApiRoute.toString())
                        .addRoute(new UserOnCallLogTimeline().crudApiPath)
                        .addRoute("/acknowledge/" + itemId.toString())).toString(),
                });
            }
            catch (error) {
                return next(error);
            }
        });
        // This is the link that actually acknowledges the notification.
        this.router.get(`${(_c = new this.entityType()
            .getCrudApiPath()) === null || _c === void 0 ? void 0 : _c.toString()}/acknowledge/:itemId`, async (req, res, next) => {
            var _a, _b;
            try {
                req = req;
                if (!req.params["itemId"]) {
                    return Response.sendErrorResponse(req, res, new BadDataException("Item ID is required"));
                }
                const itemId = new ObjectID(req.params["itemId"]);
                const timelineItem = await this.service.findOneById({
                    id: itemId,
                    select: {
                        _id: true,
                        projectId: true,
                        triggeredByIncidentId: true,
                        triggeredByAlertId: true,
                        triggeredByAlertEpisodeId: true,
                        triggeredByIncidentEpisodeId: true,
                        triggeredByAlert: {
                            title: true,
                        },
                        triggeredByIncident: {
                            title: true,
                        },
                        triggeredByAlertEpisode: {
                            title: true,
                        },
                        triggeredByIncidentEpisode: {
                            title: true,
                        },
                        acknowledgedAt: true,
                        isAcknowledged: true,
                    },
                    props: {
                        isRoot: true,
                    },
                });
                if (!timelineItem) {
                    return Response.sendErrorResponse(req, res, new BadDataException("Invalid item Id"));
                }
                const host = await DatabaseConfig.getHost();
                const httpProtocol = await DatabaseConfig.getHttpProtocol();
                const getResourceInfo = () => {
                    var _a, _b, _c, _d;
                    if (timelineItem.triggeredByIncidentId) {
                        return {
                            type: "Incident",
                            path: "incidents",
                            id: timelineItem.triggeredByIncidentId,
                            title: ((_a = timelineItem.triggeredByIncident) === null || _a === void 0 ? void 0 : _a.title) || "",
                        };
                    }
                    if (timelineItem.triggeredByIncidentEpisodeId) {
                        return {
                            type: "Incident Episode",
                            path: "incidents/episodes",
                            id: timelineItem.triggeredByIncidentEpisodeId,
                            title: ((_b = timelineItem.triggeredByIncidentEpisode) === null || _b === void 0 ? void 0 : _b.title) || "",
                        };
                    }
                    if (timelineItem.triggeredByAlertEpisodeId) {
                        return {
                            type: "Alert Episode",
                            path: "alerts/episodes",
                            id: timelineItem.triggeredByAlertEpisodeId,
                            title: ((_c = timelineItem.triggeredByAlertEpisode) === null || _c === void 0 ? void 0 : _c.title) || "",
                        };
                    }
                    if (timelineItem.triggeredByAlertId) {
                        return {
                            type: "Alert",
                            path: "alerts",
                            id: timelineItem.triggeredByAlertId,
                            title: ((_d = timelineItem.triggeredByAlert) === null || _d === void 0 ? void 0 : _d.title) || "",
                        };
                    }
                    return { type: "", path: "", id: new ObjectID(""), title: "" };
                };
                const resourceInfo = getResourceInfo();
                if (timelineItem.isAcknowledged) {
                    // already acknowledged. Then show already acknowledged page with view details button.
                    const viewDetailsRoute = new Route(DashboardRoute.toString()).addRoute(`/${(_a = timelineItem.projectId) === null || _a === void 0 ? void 0 : _a.toString()}/${resourceInfo.path}/${resourceInfo.id.toString()}`);
                    const viewDetailsUrl = new URL(httpProtocol, host, viewDetailsRoute);
                    return Response.render(req, res, "/usr/src/Common/Server/Views/ViewMessage.ejs", {
                        title: `Notification Already Acknowledged - ${resourceInfo.title}`,
                        message: `This notification has already been acknowledged.`,
                        viewDetailsText: `View ${resourceInfo.type}`,
                        viewDetailsUrl: viewDetailsUrl.toString(),
                    });
                }
                await this.service.updateOneById({
                    id: itemId,
                    data: {
                        acknowledgedAt: OneUptimeDate.getCurrentDate(),
                        isAcknowledged: true,
                        status: UserNotificationStatus.Acknowledged,
                        statusMessage: "Notification Acknowledged",
                    },
                    props: {
                        isRoot: true,
                    },
                });
                // redirect to dashboard to the resource page.
                if (resourceInfo.path) {
                    const resourceRoute = new Route(DashboardRoute.toString()).addRoute(`/${(_b = timelineItem.projectId) === null || _b === void 0 ? void 0 : _b.toString()}/${resourceInfo.path}/${resourceInfo.id.toString()}`);
                    return Response.redirect(req, res, new URL(httpProtocol, host, resourceRoute));
                }
                return Response.sendErrorResponse(req, res, new BadDataException("Invalid item Id"));
            }
            catch (error) {
                return next(error);
            }
        });
    }
}
//# sourceMappingURL=UserOnCallLogTimelineAPI.js.map