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 ObjectID from "../../Types/ObjectID";
import DatabaseService from "./DatabaseService";
import WorkspaceNotificationSummary from "../../Models/DatabaseModels/WorkspaceNotificationSummary";
import WorkspaceNotificationSummaryType from "../../Types/Workspace/NotificationSummary/WorkspaceNotificationSummaryType";
import WorkspaceNotificationSummaryItem from "../../Types/Workspace/NotificationSummary/WorkspaceNotificationSummaryItem";
import BadDataException from "../../Types/Exception/BadDataException";
import IncidentService from "./IncidentService";
import AlertService from "./AlertService";
import IncidentEpisodeService from "./IncidentEpisodeService";
import AlertEpisodeService from "./AlertEpisodeService";
import IncidentStateTimelineService from "./IncidentStateTimelineService";
import AlertStateTimelineService from "./AlertStateTimelineService";
import WorkspaceNotificationLogService from "./WorkspaceNotificationLogService";
import WorkspaceNotificationStatus from "../../Types/Workspace/WorkspaceNotificationStatus";
import WorkspaceNotificationActionType from "../../Types/Workspace/WorkspaceNotificationActionType";
import logger from "../Utils/Logger";
import OneUptimeDate from "../../Types/Date";
import QueryHelper from "../Types/Database/QueryHelper";
import WorkspaceUtil from "../Utils/Workspace/Workspace";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
import URL from "../../Types/API/URL";
import DatabaseConfig from "../DatabaseConfig";
import { NotificationRuleConditionCheckOn, } from "../../Types/Workspace/NotificationRules/NotificationRuleCondition";
import FilterCondition from "../../Types/Filter/FilterCondition";
import { WorkspaceNotificationRuleUtil } from "../../Types/Workspace/NotificationRules/NotificationRuleUtil";
export class Service extends DatabaseService {
    constructor() {
        super(WorkspaceNotificationSummary);
    }
    async testSummary(data) {
        await this.sendSummary({ summaryId: data.summaryId, isTest: true });
    }
    async sendSummary(data) {
        const summary = await this.findOneById({
            id: data.summaryId,
            select: {
                projectId: true,
                name: true,
                workspaceType: true,
                summaryType: true,
                recurringInterval: true,
                numberOfDaysOfData: true,
                channelNames: true,
                teamName: true,
                summaryItems: true,
                filters: true,
                filterCondition: true,
            },
            props: {
                isRoot: true,
            },
        });
        if (!summary) {
            throw new BadDataException("Summary not found");
        }
        if (!summary.projectId) {
            throw new BadDataException("Summary project ID not found");
        }
        if (!summary.channelNames || summary.channelNames.length === 0) {
            throw new BadDataException("No channel names configured for summary");
        }
        if (!summary.summaryItems || summary.summaryItems.length === 0) {
            throw new BadDataException("No summary items selected");
        }
        const messageBlocks = await this.buildSummaryMessageBlocks({ summary });
        const messagePayload = {
            _type: "WorkspaceMessagePayload",
            channelNames: summary.channelNames,
            channelIds: [],
            messageBlocks: messageBlocks,
            workspaceType: summary.workspaceType,
            teamId: summary.teamName || undefined,
        };
        try {
            await WorkspaceUtil.postMessageToAllWorkspaceChannelsAsBot({
                projectId: summary.projectId,
                messagePayloadsByWorkspace: [messagePayload],
            });
            // Log successful send
            for (const channelName of summary.channelNames) {
                await WorkspaceNotificationLogService.createWorkspaceLog({
                    projectId: summary.projectId,
                    workspaceType: summary.workspaceType,
                    channelName: channelName,
                    actionType: WorkspaceNotificationActionType.SendMessage,
                    status: WorkspaceNotificationStatus.Success,
                    statusMessage: data.isTest
                        ? "Test summary sent successfully"
                        : "Summary sent successfully",
                    message: `${summary.summaryType || ""} summary "${summary.name || "Untitled"}" sent to channel "${channelName}"`,
                }, { isRoot: true });
            }
        }
        catch (err) {
            // Log failed send
            for (const channelName of summary.channelNames) {
                await WorkspaceNotificationLogService.createWorkspaceLog({
                    projectId: summary.projectId,
                    workspaceType: summary.workspaceType,
                    channelName: channelName,
                    actionType: WorkspaceNotificationActionType.SendMessage,
                    status: WorkspaceNotificationStatus.Error,
                    statusMessage: err instanceof Error ? err.message : "Unknown error",
                    message: `Failed to send ${summary.summaryType || ""} summary "${summary.name || "Untitled"}" to channel "${channelName}"`,
                }, { isRoot: true }).catch((logErr) => {
                    logger.error("Failed to create workspace notification log for summary send failure");
                    logger.error(logErr);
                });
            }
            throw err; // Re-throw so caller knows it failed
        }
        if (!data.isTest) {
            await this.updateOneById({
                id: data.summaryId,
                data: {
                    lastSentAt: OneUptimeDate.getCurrentDate(),
                },
                props: {
                    isRoot: true,
                },
            });
        }
    }
    // ───────────────────────── helpers ─────────────────────────
    static divider() {
        return { _type: "WorkspacePayloadDivider" };
    }
    static header(text) {
        return { _type: "WorkspacePayloadHeader", text };
    }
    static md(text) {
        return { _type: "WorkspacePayloadMarkdown", text };
    }
    static bold(text) {
        return `**${text}**`;
    }
    static link(url, text) {
        return `[${text}](${url})`;
    }
    static formatDuration(totalMinutes) {
        if (totalMinutes < 1) {
            return "< 1m";
        }
        const days = Math.floor(totalMinutes / 1440);
        const hours = Math.floor((totalMinutes % 1440) / 60);
        const mins = Math.round(totalMinutes % 60);
        const parts = [];
        if (days > 0) {
            parts.push(`${days}d`);
        }
        if (hours > 0) {
            parts.push(`${hours}h`);
        }
        if (mins > 0 || parts.length === 0) {
            parts.push(`${mins}m`);
        }
        return parts.join(" ");
    }
    static formatDate(date) {
        return OneUptimeDate.getDateAsLocalFormattedString(date, true);
    }
    static has(items, item) {
        if (items.includes(WorkspaceNotificationSummaryItem.All)) {
            return true;
        }
        return items.includes(item);
    }
    // Check if an item matches the summary's filter conditions
    static matchesFilters(data) {
        if (!data.filters || data.filters.length === 0) {
            return true; // no filters = include everything
        }
        const rule = {
            filters: data.filters,
            filterCondition: data.filterCondition || FilterCondition.Any,
        };
        return WorkspaceNotificationRuleUtil.isRuleMatching({
            notificationRule: rule,
            values: data.values,
        });
    }
    // Build values map for an incident
    static buildIncidentValues(incident) {
        var _a, _b, _c, _d, _e, _f;
        return {
            [NotificationRuleConditionCheckOn.IncidentTitle]: incident.title || "",
            [NotificationRuleConditionCheckOn.IncidentDescription]: incident.description || "",
            [NotificationRuleConditionCheckOn.IncidentSeverity]: ((_b = (_a = incident.incidentSeverity) === null || _a === void 0 ? void 0 : _a._id) === null || _b === void 0 ? void 0 : _b.toString()) || "",
            [NotificationRuleConditionCheckOn.IncidentState]: ((_d = (_c = incident.currentIncidentState) === null || _c === void 0 ? void 0 : _c._id) === null || _d === void 0 ? void 0 : _d.toString()) || "",
            [NotificationRuleConditionCheckOn.IncidentLabels]: ((_e = incident.labels) === null || _e === void 0 ? void 0 : _e.map((l) => {
                var _a;
                return ((_a = l._id) === null || _a === void 0 ? void 0 : _a.toString()) || "";
            })) || [],
            [NotificationRuleConditionCheckOn.Monitors]: ((_f = incident.monitors) === null || _f === void 0 ? void 0 : _f.map((m) => {
                var _a;
                return ((_a = m._id) === null || _a === void 0 ? void 0 : _a.toString()) || "";
            })) || [],
            // unused for incidents
            [NotificationRuleConditionCheckOn.MonitorName]: undefined,
            [NotificationRuleConditionCheckOn.MonitorType]: undefined,
            [NotificationRuleConditionCheckOn.MonitorStatus]: undefined,
            [NotificationRuleConditionCheckOn.AlertTitle]: undefined,
            [NotificationRuleConditionCheckOn.AlertDescription]: undefined,
            [NotificationRuleConditionCheckOn.AlertSeverity]: undefined,
            [NotificationRuleConditionCheckOn.AlertState]: undefined,
            [NotificationRuleConditionCheckOn.AlertLabels]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceTitle]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceDescription]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceState]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceLabels]: undefined,
            [NotificationRuleConditionCheckOn.MonitorLabels]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyName]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyDescription]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyLabels]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeTitle]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeDescription]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeSeverity]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeState]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeLabels]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeTitle]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeDescription]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeSeverity]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeState]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeLabels]: undefined,
        };
    }
    // Build values map for an alert
    static buildAlertValues(alert) {
        var _a, _b, _c, _d, _e, _f;
        return {
            [NotificationRuleConditionCheckOn.AlertTitle]: alert.title || "",
            [NotificationRuleConditionCheckOn.AlertDescription]: alert.description || "",
            [NotificationRuleConditionCheckOn.AlertSeverity]: ((_b = (_a = alert.alertSeverity) === null || _a === void 0 ? void 0 : _a._id) === null || _b === void 0 ? void 0 : _b.toString()) || "",
            [NotificationRuleConditionCheckOn.AlertState]: ((_d = (_c = alert.currentAlertState) === null || _c === void 0 ? void 0 : _c._id) === null || _d === void 0 ? void 0 : _d.toString()) || "",
            [NotificationRuleConditionCheckOn.AlertLabels]: ((_e = alert.labels) === null || _e === void 0 ? void 0 : _e.map((l) => {
                var _a;
                return ((_a = l._id) === null || _a === void 0 ? void 0 : _a.toString()) || "";
            })) || [],
            [NotificationRuleConditionCheckOn.Monitors]: ((_f = alert.monitor) === null || _f === void 0 ? void 0 : _f._id)
                ? [alert.monitor._id.toString()]
                : [],
            // unused for alerts
            [NotificationRuleConditionCheckOn.MonitorName]: undefined,
            [NotificationRuleConditionCheckOn.MonitorType]: undefined,
            [NotificationRuleConditionCheckOn.MonitorStatus]: undefined,
            [NotificationRuleConditionCheckOn.IncidentTitle]: undefined,
            [NotificationRuleConditionCheckOn.IncidentDescription]: undefined,
            [NotificationRuleConditionCheckOn.IncidentSeverity]: undefined,
            [NotificationRuleConditionCheckOn.IncidentState]: undefined,
            [NotificationRuleConditionCheckOn.IncidentLabels]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceTitle]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceDescription]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceState]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceLabels]: undefined,
            [NotificationRuleConditionCheckOn.MonitorLabels]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyName]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyDescription]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyLabels]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeTitle]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeDescription]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeSeverity]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeState]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeLabels]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeTitle]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeDescription]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeSeverity]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeState]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeLabels]: undefined,
        };
    }
    // Build values map for an incident episode
    static buildIncidentEpisodeValues(episode) {
        var _a, _b, _c, _d, _e;
        return {
            [NotificationRuleConditionCheckOn.IncidentEpisodeTitle]: episode.title || "",
            [NotificationRuleConditionCheckOn.IncidentEpisodeDescription]: episode.description || "",
            [NotificationRuleConditionCheckOn.IncidentEpisodeSeverity]: ((_b = (_a = episode.incidentSeverity) === null || _a === void 0 ? void 0 : _a._id) === null || _b === void 0 ? void 0 : _b.toString()) || "",
            [NotificationRuleConditionCheckOn.IncidentEpisodeState]: ((_d = (_c = episode.currentIncidentState) === null || _c === void 0 ? void 0 : _c._id) === null || _d === void 0 ? void 0 : _d.toString()) || "",
            [NotificationRuleConditionCheckOn.IncidentEpisodeLabels]: ((_e = episode.labels) === null || _e === void 0 ? void 0 : _e.map((l) => {
                var _a;
                return ((_a = l._id) === null || _a === void 0 ? void 0 : _a.toString()) || "";
            })) || [],
            // unused for incident episodes
            [NotificationRuleConditionCheckOn.IncidentTitle]: undefined,
            [NotificationRuleConditionCheckOn.IncidentDescription]: undefined,
            [NotificationRuleConditionCheckOn.IncidentSeverity]: undefined,
            [NotificationRuleConditionCheckOn.IncidentState]: undefined,
            [NotificationRuleConditionCheckOn.IncidentLabels]: undefined,
            [NotificationRuleConditionCheckOn.AlertTitle]: undefined,
            [NotificationRuleConditionCheckOn.AlertDescription]: undefined,
            [NotificationRuleConditionCheckOn.AlertSeverity]: undefined,
            [NotificationRuleConditionCheckOn.AlertState]: undefined,
            [NotificationRuleConditionCheckOn.AlertLabels]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeTitle]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeDescription]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeSeverity]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeState]: undefined,
            [NotificationRuleConditionCheckOn.AlertEpisodeLabels]: undefined,
            [NotificationRuleConditionCheckOn.Monitors]: undefined,
            [NotificationRuleConditionCheckOn.MonitorName]: undefined,
            [NotificationRuleConditionCheckOn.MonitorType]: undefined,
            [NotificationRuleConditionCheckOn.MonitorStatus]: undefined,
            [NotificationRuleConditionCheckOn.MonitorLabels]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceTitle]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceDescription]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceState]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceLabels]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyName]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyDescription]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyLabels]: undefined,
        };
    }
    // Build values map for an alert episode
    static buildAlertEpisodeValues(episode) {
        var _a, _b, _c, _d, _e;
        return {
            [NotificationRuleConditionCheckOn.AlertEpisodeTitle]: episode.title || "",
            [NotificationRuleConditionCheckOn.AlertEpisodeDescription]: episode.description || "",
            [NotificationRuleConditionCheckOn.AlertEpisodeSeverity]: ((_b = (_a = episode.alertSeverity) === null || _a === void 0 ? void 0 : _a._id) === null || _b === void 0 ? void 0 : _b.toString()) || "",
            [NotificationRuleConditionCheckOn.AlertEpisodeState]: ((_d = (_c = episode.currentAlertState) === null || _c === void 0 ? void 0 : _c._id) === null || _d === void 0 ? void 0 : _d.toString()) || "",
            [NotificationRuleConditionCheckOn.AlertEpisodeLabels]: ((_e = episode.labels) === null || _e === void 0 ? void 0 : _e.map((l) => {
                var _a;
                return ((_a = l._id) === null || _a === void 0 ? void 0 : _a.toString()) || "";
            })) || [],
            // unused for alert episodes
            [NotificationRuleConditionCheckOn.IncidentTitle]: undefined,
            [NotificationRuleConditionCheckOn.IncidentDescription]: undefined,
            [NotificationRuleConditionCheckOn.IncidentSeverity]: undefined,
            [NotificationRuleConditionCheckOn.IncidentState]: undefined,
            [NotificationRuleConditionCheckOn.IncidentLabels]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeTitle]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeDescription]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeSeverity]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeState]: undefined,
            [NotificationRuleConditionCheckOn.IncidentEpisodeLabels]: undefined,
            [NotificationRuleConditionCheckOn.AlertTitle]: undefined,
            [NotificationRuleConditionCheckOn.AlertDescription]: undefined,
            [NotificationRuleConditionCheckOn.AlertSeverity]: undefined,
            [NotificationRuleConditionCheckOn.AlertState]: undefined,
            [NotificationRuleConditionCheckOn.AlertLabels]: undefined,
            [NotificationRuleConditionCheckOn.Monitors]: undefined,
            [NotificationRuleConditionCheckOn.MonitorName]: undefined,
            [NotificationRuleConditionCheckOn.MonitorType]: undefined,
            [NotificationRuleConditionCheckOn.MonitorStatus]: undefined,
            [NotificationRuleConditionCheckOn.MonitorLabels]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceTitle]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceDescription]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceState]: undefined,
            [NotificationRuleConditionCheckOn.ScheduledMaintenanceLabels]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyName]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyDescription]: undefined,
            [NotificationRuleConditionCheckOn.OnCallDutyPolicyLabels]: undefined,
        };
    }
    // ───────────────────────── main builder ─────────────────────────
    async buildSummaryMessageBlocks(data) {
        const { summary } = data;
        const blocks = [];
        const items = summary.summaryItems;
        const days = summary.numberOfDaysOfData || 7;
        const type = summary.summaryType;
        const fromDate = OneUptimeDate.addRemoveDays(OneUptimeDate.getCurrentDate(), -days);
        const fromDateStr = Service.formatDate(fromDate);
        const toDateStr = Service.formatDate(OneUptimeDate.getCurrentDate());
        // Title
        blocks.push(Service.header(`${type} Summary — ${fromDateStr} to ${toDateStr}`));
        blocks.push(Service.md(`_Reporting period: ${Service.bold(String(days))} day${days !== 1 ? "s" : ""}_`));
        blocks.push(Service.divider());
        // Build type-specific content
        if (type === WorkspaceNotificationSummaryType.Incident ||
            type === WorkspaceNotificationSummaryType.IncidentEpisode) {
            await this.buildIncidentBlocks({
                blocks,
                items,
                type,
                fromDate,
                projectId: summary.projectId,
                filters: summary.filters || undefined,
                filterCondition: summary.filterCondition || undefined,
            });
        }
        else {
            await this.buildAlertBlocks({
                blocks,
                items,
                type,
                fromDate,
                projectId: summary.projectId,
                filters: summary.filters || undefined,
                filterCondition: summary.filterCondition || undefined,
            });
        }
        // Footer
        blocks.push(Service.divider());
        blocks.push(Service.md(`_Sent by OneUptime  •  ${summary.name || "Untitled"}_`));
        return blocks;
    }
    // ───────────────────────── Incidents ─────────────────────────
    async buildIncidentBlocks(data) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
        if (data.type === WorkspaceNotificationSummaryType.IncidentEpisode) {
            await this.buildIncidentEpisodeBlocks(data);
            return;
        }
        const { blocks, items, fromDate, projectId } = data;
        let incidents = await IncidentService.findAllBy({
            query: {
                projectId,
                createdAt: QueryHelper.greaterThanEqualTo(fromDate),
            },
            select: {
                _id: true,
                title: true,
                description: true,
                incidentNumber: true,
                incidentNumberWithPrefix: true,
                incidentSeverity: { name: true, _id: true },
                currentIncidentState: {
                    name: true,
                    _id: true,
                    isResolvedState: true,
                    isAcknowledgedState: true,
                },
                labels: { _id: true, name: true },
                monitors: { name: true, _id: true },
                createdAt: true,
                declaredAt: true,
            },
            props: { isRoot: true },
        });
        // Apply filters
        if (data.filters && data.filters.length > 0) {
            incidents = incidents.filter((inc) => {
                return Service.matchesFilters({
                    filters: data.filters,
                    filterCondition: data.filterCondition,
                    values: Service.buildIncidentValues(inc),
                });
            });
        }
        const dashboardUrl = await DatabaseConfig.getDashboardUrl();
        // Overview stats
        if (Service.has(items, WorkspaceNotificationSummaryItem.TotalCount)) {
            const resolved = incidents.filter((i) => {
                var _a;
                return (_a = i.currentIncidentState) === null || _a === void 0 ? void 0 : _a.isResolvedState;
            }).length;
            const open = incidents.length - resolved;
            blocks.push(Service.md(`${Service.bold("Total:")} ${incidents.length} incident${incidents.length !== 1 ? "s" : ""}  ·  ` +
                `${Service.bold("Open:")} ${open}  ·  ${Service.bold("Resolved:")} ${resolved}`));
        }
        // Severity breakdown
        if (Service.has(items, WorkspaceNotificationSummaryItem.SeverityBreakdown)) {
            const map = new Map();
            for (const i of incidents) {
                const s = ((_a = i.incidentSeverity) === null || _a === void 0 ? void 0 : _a.name) || "Unknown";
                map.set(s, (map.get(s) || 0) + 1);
            }
            if (map.size > 0) {
                const parts = [];
                for (const [sev, count] of map) {
                    parts.push(`${sev}: ${Service.bold(String(count))}`);
                }
                blocks.push(Service.md(`${Service.bold("By Severity:")}  ${parts.join("  ·  ")}`));
            }
        }
        // State breakdown
        if (Service.has(items, WorkspaceNotificationSummaryItem.StateBreakdown)) {
            const map = new Map();
            for (const i of incidents) {
                const s = ((_b = i.currentIncidentState) === null || _b === void 0 ? void 0 : _b.name) || "Unknown";
                map.set(s, (map.get(s) || 0) + 1);
            }
            if (map.size > 0) {
                const parts = [];
                for (const [state, count] of map) {
                    parts.push(`${state}: ${Service.bold(String(count))}`);
                }
                blocks.push(Service.md(`${Service.bold("By State:")}  ${parts.join("  ·  ")}`));
            }
        }
        // Timeline data for MTTA/MTTR/who
        const needTimeline = Service.has(items, WorkspaceNotificationSummaryItem.WhoAcknowledged) ||
            Service.has(items, WorkspaceNotificationSummaryItem.WhoResolved) ||
            Service.has(items, WorkspaceNotificationSummaryItem.TimeToAcknowledge) ||
            Service.has(items, WorkspaceNotificationSummaryItem.TimeToResolve);
        const tlMap = new Map();
        if (needTimeline && incidents.length > 0) {
            const ids = incidents
                .filter((i) => {
                return i._id;
            })
                .map((i) => {
                return new ObjectID(i._id.toString());
            });
            const timelines = await IncidentStateTimelineService.findAllBy({
                query: {
                    projectId,
                    incidentId: QueryHelper.any(ids),
                },
                select: {
                    incidentId: true,
                    incidentState: {
                        isAcknowledgedState: true,
                        isResolvedState: true,
                    },
                    createdByUser: { name: true, email: true },
                    createdAt: true,
                },
                props: { isRoot: true },
            });
            for (const tl of timelines) {
                const id = ((_c = tl.incidentId) === null || _c === void 0 ? void 0 : _c.toString()) || "";
                if (!tlMap.has(id)) {
                    tlMap.set(id, {});
                }
                const td = tlMap.get(id);
                const userName = ((_e = (_d = tl.createdByUser) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.toString()) ||
                    ((_g = (_f = tl.createdByUser) === null || _f === void 0 ? void 0 : _f.email) === null || _g === void 0 ? void 0 : _g.toString()) ||
                    "System";
                if (((_h = tl.incidentState) === null || _h === void 0 ? void 0 : _h.isAcknowledgedState) && !td.ackAt) {
                    td.ackBy = userName;
                    td.ackAt = tl.createdAt;
                }
                if (((_j = tl.incidentState) === null || _j === void 0 ? void 0 : _j.isResolvedState) && !td.resolvedAt) {
                    td.resolvedBy = userName;
                    td.resolvedAt = tl.createdAt;
                }
            }
            for (const inc of incidents) {
                const id = ((_k = inc._id) === null || _k === void 0 ? void 0 : _k.toString()) || "";
                if (!tlMap.has(id)) {
                    tlMap.set(id, {});
                }
                tlMap.get(id).declaredAt = inc.declaredAt || inc.createdAt;
            }
        }
        // MTTA
        if (Service.has(items, WorkspaceNotificationSummaryItem.TimeToAcknowledge)) {
            const { avg, count } = this.computeAvg(tlMap, "ack");
            blocks.push(Service.md(count > 0
                ? `${Service.bold("MTTA (Mean Time to Acknowledge):")}  ${Service.bold(Service.formatDuration(avg))}  _(${count} acknowledged)_`
                : `${Service.bold("MTTA (Mean Time to Acknowledge):")}  _No incidents acknowledged_`));
        }
        // MTTR
        if (Service.has(items, WorkspaceNotificationSummaryItem.TimeToResolve)) {
            const { avg, count } = this.computeAvg(tlMap, "resolve");
            blocks.push(Service.md(count > 0
                ? `${Service.bold("MTTR (Mean Time to Resolve):")}  ${Service.bold(Service.formatDuration(avg))}  _(${count} resolved)_`
                : `${Service.bold("MTTR (Mean Time to Resolve):")}  _No incidents resolved_`));
        }
        // Resources affected
        if (Service.has(items, WorkspaceNotificationSummaryItem.ResourcesAffected)) {
            const names = new Set();
            for (const inc of incidents) {
                if (inc.monitors) {
                    for (const m of inc.monitors) {
                        if (m.name) {
                            names.add(m.name);
                        }
                    }
                }
            }
            if (names.size > 0) {
                blocks.push(Service.md(`${Service.bold(`Resources Affected (${names.size}):`)}  ${Array.from(names).join(", ")}`));
            }
        }
        // Detailed list
        if (Service.has(items, WorkspaceNotificationSummaryItem.ListWithLinks)) {
            blocks.push(Service.divider());
            if (incidents.length === 0) {
                blocks.push(Service.md(`_No incidents reported in this period._`));
                return;
            }
            for (const inc of incidents) {
                const id = ((_l = inc._id) === null || _l === void 0 ? void 0 : _l.toString()) || "";
                const display = inc.incidentNumberWithPrefix || `#${inc.incidentNumber || ""}`;
                const linkUrl = URL.fromString(dashboardUrl.toString())
                    .addRoute(`/${projectId.toString()}/incidents/${id}`)
                    .toString();
                const td = tlMap.get(id);
                // Title line with link
                let text = `${Service.bold(Service.link(linkUrl, `${display} — ${inc.title || "Untitled"}`))}`;
                // Meta line
                const meta = [];
                if ((_m = inc.incidentSeverity) === null || _m === void 0 ? void 0 : _m.name) {
                    meta.push(`Severity: ${Service.bold(inc.incidentSeverity.name)}`);
                }
                if ((_o = inc.currentIncidentState) === null || _o === void 0 ? void 0 : _o.name) {
                    meta.push(`State: ${Service.bold(inc.currentIncidentState.name)}`);
                }
                if (inc.declaredAt) {
                    meta.push(`Declared: ${Service.formatDate(inc.declaredAt)}`);
                }
                if (meta.length > 0) {
                    text += `\n${meta.join("  ·  ")}`;
                }
                // Ack & resolve line
                const ackResolve = [];
                if (Service.has(items, WorkspaceNotificationSummaryItem.WhoAcknowledged)) {
                    if ((td === null || td === void 0 ? void 0 : td.ackBy) && (td === null || td === void 0 ? void 0 : td.ackAt)) {
                        ackResolve.push(`Ack: ${Service.bold(td.ackBy)} in ${Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt || inc.createdAt, td.ackAt))}`);
                    }
                    else if ((td === null || td === void 0 ? void 0 : td.resolvedBy) && (td === null || td === void 0 ? void 0 : td.resolvedAt)) {
                        // If not explicitly acknowledged but resolved, ack time = resolve time
                        ackResolve.push(`Ack: ${Service.bold(td.resolvedBy)} in ${Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt || inc.createdAt, td.resolvedAt))}`);
                    }
                    else {
                        ackResolve.push(`_Not yet acknowledged_`);
                    }
                }
                if (Service.has(items, WorkspaceNotificationSummaryItem.WhoResolved)) {
                    if ((td === null || td === void 0 ? void 0 : td.resolvedBy) && (td === null || td === void 0 ? void 0 : td.resolvedAt)) {
                        ackResolve.push(`Resolved: ${Service.bold(td.resolvedBy)} in ${Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt || inc.createdAt, td.resolvedAt))}`);
                    }
                    else if (!((_p = inc.currentIncidentState) === null || _p === void 0 ? void 0 : _p.isResolvedState)) {
                        ackResolve.push(`_Not yet resolved_`);
                    }
                }
                if (ackResolve.length > 0) {
                    text += `\n${ackResolve.join("  ·  ")}`;
                }
                blocks.push(Service.md(text));
            }
        }
    }
    // ───────────────────────── Incident Episodes ─────────────────────────
    async buildIncidentEpisodeBlocks(data) {
        var _a, _b, _c, _d, _e;
        const { blocks, items, fromDate, projectId } = data;
        let episodes = await IncidentEpisodeService.findAllBy({
            query: {
                projectId,
                createdAt: QueryHelper.greaterThanEqualTo(fromDate),
            },
            select: {
                _id: true,
                title: true,
                description: true,
                incidentSeverity: { name: true, _id: true },
                currentIncidentState: {
                    name: true,
                    _id: true,
                    isResolvedState: true,
                },
                labels: { _id: true, name: true },
                createdAt: true,
                resolvedAt: true,
            },
            props: { isRoot: true },
        });
        // Apply filters
        if (data.filters && data.filters.length > 0) {
            episodes = episodes.filter((ep) => {
                return Service.matchesFilters({
                    filters: data.filters,
                    filterCondition: data.filterCondition,
                    values: Service.buildIncidentEpisodeValues(ep),
                });
            });
        }
        const dashboardUrl = await DatabaseConfig.getDashboardUrl();
        if (Service.has(items, WorkspaceNotificationSummaryItem.TotalCount)) {
            const resolved = episodes.filter((e) => {
                var _a;
                return (_a = e.currentIncidentState) === null || _a === void 0 ? void 0 : _a.isResolvedState;
            }).length;
            blocks.push(Service.md(`${Service.bold("Total:")} ${episodes.length} episode${episodes.length !== 1 ? "s" : ""}  ·  ` +
                `${Service.bold("Open:")} ${episodes.length - resolved}  ·  ${Service.bold("Resolved:")} ${resolved}`));
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.SeverityBreakdown)) {
            const map = new Map();
            for (const e of episodes) {
                const s = ((_a = e.incidentSeverity) === null || _a === void 0 ? void 0 : _a.name) || "Unknown";
                map.set(s, (map.get(s) || 0) + 1);
            }
            if (map.size > 0) {
                const parts = [];
                for (const [sev, c] of map) {
                    parts.push(`${sev}: ${Service.bold(String(c))}`);
                }
                blocks.push(Service.md(`${Service.bold("By Severity:")}  ${parts.join("  ·  ")}`));
            }
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.StateBreakdown)) {
            const map = new Map();
            for (const e of episodes) {
                const s = ((_b = e.currentIncidentState) === null || _b === void 0 ? void 0 : _b.name) || "Unknown";
                map.set(s, (map.get(s) || 0) + 1);
            }
            if (map.size > 0) {
                const parts = [];
                for (const [state, c] of map) {
                    parts.push(`${state}: ${Service.bold(String(c))}`);
                }
                blocks.push(Service.md(`${Service.bold("By State:")}  ${parts.join("  ·  ")}`));
            }
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.TimeToResolve)) {
            let total = 0;
            let count = 0;
            for (const e of episodes) {
                if (e.resolvedAt && e.createdAt) {
                    total += OneUptimeDate.getMinutesBetweenTwoDates(e.createdAt, e.resolvedAt);
                    count++;
                }
            }
            blocks.push(Service.md(count > 0
                ? `${Service.bold("MTTR (Mean Time to Resolve):")}  ${Service.bold(Service.formatDuration(Math.round(total / count)))}  _(${count} resolved)_`
                : `${Service.bold("MTTR (Mean Time to Resolve):")}  _No episodes resolved_`));
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.ListWithLinks)) {
            blocks.push(Service.divider());
            if (episodes.length === 0) {
                blocks.push(Service.md(`_No incident episodes in this period._`));
                return;
            }
            for (const ep of episodes) {
                const id = ((_c = ep._id) === null || _c === void 0 ? void 0 : _c.toString()) || "";
                const linkUrl = URL.fromString(dashboardUrl.toString())
                    .addRoute(`/${projectId.toString()}/incidents/episodes/${id}`)
                    .toString();
                let text = `${Service.bold(Service.link(linkUrl, ep.title || "Untitled Episode"))}`;
                const meta = [];
                if ((_d = ep.incidentSeverity) === null || _d === void 0 ? void 0 : _d.name) {
                    meta.push(`Severity: ${Service.bold(ep.incidentSeverity.name)}`);
                }
                if ((_e = ep.currentIncidentState) === null || _e === void 0 ? void 0 : _e.name) {
                    meta.push(`State: ${Service.bold(ep.currentIncidentState.name)}`);
                }
                if (ep.createdAt) {
                    meta.push(`Created: ${Service.formatDate(ep.createdAt)}`);
                }
                if (ep.resolvedAt && ep.createdAt) {
                    meta.push(`Resolved in ${Service.bold(Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(ep.createdAt, ep.resolvedAt)))}`);
                }
                if (meta.length > 0) {
                    text += `\n${meta.join("  ·  ")}`;
                }
                blocks.push(Service.md(text));
            }
        }
    }
    // ───────────────────────── Alerts ─────────────────────────
    async buildAlertBlocks(data) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
        if (data.type === WorkspaceNotificationSummaryType.AlertEpisode) {
            await this.buildAlertEpisodeBlocks(data);
            return;
        }
        const { blocks, items, fromDate, projectId } = data;
        let alerts = await AlertService.findAllBy({
            query: {
                projectId,
                createdAt: QueryHelper.greaterThanEqualTo(fromDate),
            },
            select: {
                _id: true,
                title: true,
                description: true,
                alertNumber: true,
                alertNumberWithPrefix: true,
                alertSeverity: { name: true, _id: true },
                currentAlertState: {
                    name: true,
                    _id: true,
                    isResolvedState: true,
                    isAcknowledgedState: true,
                },
                labels: { _id: true, name: true },
                monitor: { name: true, _id: true },
                createdAt: true,
            },
            props: { isRoot: true },
        });
        // Apply filters
        if (data.filters && data.filters.length > 0) {
            alerts = alerts.filter((alert) => {
                return Service.matchesFilters({
                    filters: data.filters,
                    filterCondition: data.filterCondition,
                    values: Service.buildAlertValues(alert),
                });
            });
        }
        const dashboardUrl = await DatabaseConfig.getDashboardUrl();
        if (Service.has(items, WorkspaceNotificationSummaryItem.TotalCount)) {
            const resolved = alerts.filter((a) => {
                var _a;
                return (_a = a.currentAlertState) === null || _a === void 0 ? void 0 : _a.isResolvedState;
            }).length;
            blocks.push(Service.md(`${Service.bold("Total:")} ${alerts.length} alert${alerts.length !== 1 ? "s" : ""}  ·  ` +
                `${Service.bold("Open:")} ${alerts.length - resolved}  ·  ${Service.bold("Resolved:")} ${resolved}`));
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.SeverityBreakdown)) {
            const map = new Map();
            for (const a of alerts) {
                const s = ((_a = a.alertSeverity) === null || _a === void 0 ? void 0 : _a.name) || "Unknown";
                map.set(s, (map.get(s) || 0) + 1);
            }
            if (map.size > 0) {
                const parts = [];
                for (const [sev, c] of map) {
                    parts.push(`${sev}: ${Service.bold(String(c))}`);
                }
                blocks.push(Service.md(`${Service.bold("By Severity:")}  ${parts.join("  ·  ")}`));
            }
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.StateBreakdown)) {
            const map = new Map();
            for (const a of alerts) {
                const s = ((_b = a.currentAlertState) === null || _b === void 0 ? void 0 : _b.name) || "Unknown";
                map.set(s, (map.get(s) || 0) + 1);
            }
            if (map.size > 0) {
                const parts = [];
                for (const [state, c] of map) {
                    parts.push(`${state}: ${Service.bold(String(c))}`);
                }
                blocks.push(Service.md(`${Service.bold("By State:")}  ${parts.join("  ·  ")}`));
            }
        }
        // Timeline data
        const needTimeline = Service.has(items, WorkspaceNotificationSummaryItem.WhoAcknowledged) ||
            Service.has(items, WorkspaceNotificationSummaryItem.WhoResolved) ||
            Service.has(items, WorkspaceNotificationSummaryItem.TimeToAcknowledge) ||
            Service.has(items, WorkspaceNotificationSummaryItem.TimeToResolve);
        const tlMap = new Map();
        if (needTimeline && alerts.length > 0) {
            const ids = alerts
                .filter((a) => {
                return a._id;
            })
                .map((a) => {
                return new ObjectID(a._id.toString());
            });
            const timelines = await AlertStateTimelineService.findAllBy({
                query: { projectId, alertId: QueryHelper.any(ids) },
                select: {
                    alertId: true,
                    alertState: {
                        isAcknowledgedState: true,
                        isResolvedState: true,
                    },
                    createdByUser: { name: true, email: true },
                    createdAt: true,
                },
                props: { isRoot: true },
            });
            for (const tl of timelines) {
                const id = ((_c = tl.alertId) === null || _c === void 0 ? void 0 : _c.toString()) || "";
                if (!tlMap.has(id)) {
                    tlMap.set(id, {});
                }
                const td = tlMap.get(id);
                const userName = ((_e = (_d = tl.createdByUser) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.toString()) ||
                    ((_g = (_f = tl.createdByUser) === null || _f === void 0 ? void 0 : _f.email) === null || _g === void 0 ? void 0 : _g.toString()) ||
                    "System";
                if (((_h = tl.alertState) === null || _h === void 0 ? void 0 : _h.isAcknowledgedState) && !td.ackAt) {
                    td.ackBy = userName;
                    td.ackAt = tl.createdAt;
                }
                if (((_j = tl.alertState) === null || _j === void 0 ? void 0 : _j.isResolvedState) && !td.resolvedAt) {
                    td.resolvedBy = userName;
                    td.resolvedAt = tl.createdAt;
                }
            }
            for (const a of alerts) {
                const id = ((_k = a._id) === null || _k === void 0 ? void 0 : _k.toString()) || "";
                if (!tlMap.has(id)) {
                    tlMap.set(id, {});
                }
                tlMap.get(id).declaredAt = a.createdAt;
            }
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.TimeToAcknowledge)) {
            const { avg, count } = this.computeAvg(tlMap, "ack");
            blocks.push(Service.md(count > 0
                ? `${Service.bold("MTTA (Mean Time to Acknowledge):")}  ${Service.bold(Service.formatDuration(avg))}  _(${count} acknowledged)_`
                : `${Service.bold("MTTA (Mean Time to Acknowledge):")}  _No alerts acknowledged_`));
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.TimeToResolve)) {
            const { avg, count } = this.computeAvg(tlMap, "resolve");
            blocks.push(Service.md(count > 0
                ? `${Service.bold("MTTR (Mean Time to Resolve):")}  ${Service.bold(Service.formatDuration(avg))}  _(${count} resolved)_`
                : `${Service.bold("MTTR (Mean Time to Resolve):")}  _No alerts resolved_`));
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.ResourcesAffected)) {
            const names = new Set();
            for (const a of alerts) {
                if ((_l = a.monitor) === null || _l === void 0 ? void 0 : _l.name) {
                    names.add(a.monitor.name);
                }
            }
            if (names.size > 0) {
                blocks.push(Service.md(`${Service.bold(`Resources Affected (${names.size}):`)}  ${Array.from(names).join(", ")}`));
            }
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.ListWithLinks)) {
            blocks.push(Service.divider());
            if (alerts.length === 0) {
                blocks.push(Service.md(`_No alerts reported in this period._`));
                return;
            }
            for (const a of alerts) {
                const id = ((_m = a._id) === null || _m === void 0 ? void 0 : _m.toString()) || "";
                const display = a.alertNumberWithPrefix || `#${a.alertNumber || ""}`;
                const linkUrl = URL.fromString(dashboardUrl.toString())
                    .addRoute(`/${projectId.toString()}/alerts/${id}`)
                    .toString();
                const td = tlMap.get(id);
                let text = `${Service.bold(Service.link(linkUrl, `${display} — ${a.title || "Untitled"}`))}`;
                const meta = [];
                if ((_o = a.alertSeverity) === null || _o === void 0 ? void 0 : _o.name) {
                    meta.push(`Severity: ${Service.bold(a.alertSeverity.name)}`);
                }
                if ((_p = a.currentAlertState) === null || _p === void 0 ? void 0 : _p.name) {
                    meta.push(`State: ${Service.bold(a.currentAlertState.name)}`);
                }
                if (a.createdAt) {
                    meta.push(`Created: ${Service.formatDate(a.createdAt)}`);
                }
                if (meta.length > 0) {
                    text += `\n${meta.join("  ·  ")}`;
                }
                const ackResolve = [];
                if (Service.has(items, WorkspaceNotificationSummaryItem.WhoAcknowledged)) {
                    if ((td === null || td === void 0 ? void 0 : td.ackBy) && (td === null || td === void 0 ? void 0 : td.ackAt)) {
                        ackResolve.push(`Ack: ${Service.bold(td.ackBy)} in ${Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt || a.createdAt, td.ackAt))}`);
                    }
                    else if ((td === null || td === void 0 ? void 0 : td.resolvedBy) && (td === null || td === void 0 ? void 0 : td.resolvedAt)) {
                        // If not explicitly acknowledged but resolved, ack time = resolve time
                        ackResolve.push(`Ack: ${Service.bold(td.resolvedBy)} in ${Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt || a.createdAt, td.resolvedAt))}`);
                    }
                    else {
                        ackResolve.push(`_Not yet acknowledged_`);
                    }
                }
                if (Service.has(items, WorkspaceNotificationSummaryItem.WhoResolved)) {
                    if ((td === null || td === void 0 ? void 0 : td.resolvedBy) && (td === null || td === void 0 ? void 0 : td.resolvedAt)) {
                        ackResolve.push(`Resolved: ${Service.bold(td.resolvedBy)} in ${Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt || a.createdAt, td.resolvedAt))}`);
                    }
                    else if (!((_q = a.currentAlertState) === null || _q === void 0 ? void 0 : _q.isResolvedState)) {
                        ackResolve.push(`_Not yet resolved_`);
                    }
                }
                if (ackResolve.length > 0) {
                    text += `\n${ackResolve.join("  ·  ")}`;
                }
                blocks.push(Service.md(text));
            }
        }
    }
    // ───────────────────────── Alert Episodes ─────────────────────────
    async buildAlertEpisodeBlocks(data) {
        var _a, _b, _c, _d, _e;
        const { blocks, items, fromDate, projectId } = data;
        let episodes = await AlertEpisodeService.findAllBy({
            query: {
                projectId,
                createdAt: QueryHelper.greaterThanEqualTo(fromDate),
            },
            select: {
                _id: true,
                title: true,
                description: true,
                alertSeverity: { name: true, _id: true },
                currentAlertState: { name: true, _id: true, isResolvedState: true },
                labels: { _id: true, name: true },
                createdAt: true,
                resolvedAt: true,
            },
            props: { isRoot: true },
        });
        // Apply filters
        if (data.filters && data.filters.length > 0) {
            episodes = episodes.filter((ep) => {
                return Service.matchesFilters({
                    filters: data.filters,
                    filterCondition: data.filterCondition,
                    values: Service.buildAlertEpisodeValues(ep),
                });
            });
        }
        const dashboardUrl = await DatabaseConfig.getDashboardUrl();
        if (Service.has(items, WorkspaceNotificationSummaryItem.TotalCount)) {
            const resolved = episodes.filter((e) => {
                var _a;
                return (_a = e.currentAlertState) === null || _a === void 0 ? void 0 : _a.isResolvedState;
            }).length;
            blocks.push(Service.md(`${Service.bold("Total:")} ${episodes.length} episode${episodes.length !== 1 ? "s" : ""}  ·  ` +
                `${Service.bold("Open:")} ${episodes.length - resolved}  ·  ${Service.bold("Resolved:")} ${resolved}`));
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.SeverityBreakdown)) {
            const map = new Map();
            for (const e of episodes) {
                const s = ((_a = e.alertSeverity) === null || _a === void 0 ? void 0 : _a.name) || "Unknown";
                map.set(s, (map.get(s) || 0) + 1);
            }
            if (map.size > 0) {
                const parts = [];
                for (const [sev, c] of map) {
                    parts.push(`${sev}: ${Service.bold(String(c))}`);
                }
                blocks.push(Service.md(`${Service.bold("By Severity:")}  ${parts.join("  ·  ")}`));
            }
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.StateBreakdown)) {
            const map = new Map();
            for (const e of episodes) {
                const s = ((_b = e.currentAlertState) === null || _b === void 0 ? void 0 : _b.name) || "Unknown";
                map.set(s, (map.get(s) || 0) + 1);
            }
            if (map.size > 0) {
                const parts = [];
                for (const [state, c] of map) {
                    parts.push(`${state}: ${Service.bold(String(c))}`);
                }
                blocks.push(Service.md(`${Service.bold("By State:")}  ${parts.join("  ·  ")}`));
            }
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.TimeToResolve)) {
            let total = 0;
            let count = 0;
            for (const e of episodes) {
                if (e.resolvedAt && e.createdAt) {
                    total += OneUptimeDate.getMinutesBetweenTwoDates(e.createdAt, e.resolvedAt);
                    count++;
                }
            }
            blocks.push(Service.md(count > 0
                ? `${Service.bold("MTTR (Mean Time to Resolve):")}  ${Service.bold(Service.formatDuration(Math.round(total / count)))}  _(${count} resolved)_`
                : `${Service.bold("MTTR (Mean Time to Resolve):")}  _No episodes resolved_`));
        }
        if (Service.has(items, WorkspaceNotificationSummaryItem.ListWithLinks)) {
            blocks.push(Service.divider());
            if (episodes.length === 0) {
                blocks.push(Service.md(`_No alert episodes in this period._`));
                return;
            }
            for (const ep of episodes) {
                const id = ((_c = ep._id) === null || _c === void 0 ? void 0 : _c.toString()) || "";
                const linkUrl = URL.fromString(dashboardUrl.toString())
                    .addRoute(`/${projectId.toString()}/alerts/episodes/${id}`)
                    .toString();
                let text = `${Service.bold(Service.link(linkUrl, ep.title || "Untitled Episode"))}`;
                const meta = [];
                if ((_d = ep.alertSeverity) === null || _d === void 0 ? void 0 : _d.name) {
                    meta.push(`Severity: ${Service.bold(ep.alertSeverity.name)}`);
                }
                if ((_e = ep.currentAlertState) === null || _e === void 0 ? void 0 : _e.name) {
                    meta.push(`State: ${Service.bold(ep.currentAlertState.name)}`);
                }
                if (ep.createdAt) {
                    meta.push(`Created: ${Service.formatDate(ep.createdAt)}`);
                }
                if (ep.resolvedAt && ep.createdAt) {
                    meta.push(`Resolved in ${Service.bold(Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(ep.createdAt, ep.resolvedAt)))}`);
                }
                if (meta.length > 0) {
                    text += `\n${meta.join("  ·  ")}`;
                }
                blocks.push(Service.md(text));
            }
        }
    }
    // ───────────────────────── Utilities ─────────────────────────
    computeAvg(tlMap, kind) {
        let total = 0;
        let count = 0;
        for (const [, td] of tlMap) {
            // For ack: if not explicitly acknowledged but resolved, use resolve time as ack time
            const eventTime = kind === "ack" ? td.ackAt || td.resolvedAt : td.resolvedAt;
            if (eventTime && td.declaredAt) {
                total += OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt, eventTime);
                count++;
            }
        }
        return { avg: count > 0 ? Math.round(total / count) : 0, count };
    }
}
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "testSummary", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "sendSummary", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "buildSummaryMessageBlocks", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "buildIncidentBlocks", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "buildIncidentEpisodeBlocks", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "buildAlertBlocks", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "buildAlertEpisodeBlocks", null);
export default new Service();
//# sourceMappingURL=WorkspaceNotificationSummaryService.js.map