"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageRecordService = void 0;
const messageRecordModel_1 = require("../models/messageRecordModel");
class MessageRecordService {
    /**
     * 创建一条新的消息推送记录
     * @param recordData 消息记录数据
     * @returns 新创建的消息记录对象
     */
    async createMessageRecord(recordData) {
        const newRecord = new messageRecordModel_1.MessageRecord(recordData);
        return await newRecord.save();
    }
    /**
     * 分页获取消息推送记录，支持筛选和排序
     * @param page 页码
     * @param limit 每页记录数
     * @param filters 筛选条件
     * @param sortField 排序字段
     * @param sortOrder 排序顺序 ('asc' 或 'desc')
     * @returns 包含记录和总数的对象
     */
    async getPaginatedRecords(page = 1, limit = 10, filters = {}, sortField = "createdAt", sortOrder = "desc") {
        // 构建查询条件
        const query = {};
        if (filters.uid) {
            query.uid = filters.uid;
        }
        if (filters.activityName) {
            query.activityName = filters.activityName;
        }
        if (filters.templateName) {
            query.templateName = filters.templateName;
        }
        if (filters.status !== undefined) {
            query.status = filters.status;
        }
        const sort = {};
        sort[sortField] = sortOrder === "asc" ? 1 : -1;
        const skip = (page - 1) * limit;
        const records = await messageRecordModel_1.MessageRecord.find(query).sort(sort).skip(skip).limit(limit);
        const total = await messageRecordModel_1.MessageRecord.countDocuments(query);
        return { records, total };
    }
    /**
     * 根据用户UID获取其所有消息推送记录
     * @param uid 用户UID
     * @returns 消息记录列表
     */
    async getRecordsByUid(uid) {
        return await messageRecordModel_1.MessageRecord.find({ uid }).sort({ createdAt: -1 });
    }
    /**
     * 根据消息活动ID获取所有相关的推送记录
     * @param activityId 消息活动ID
     * @returns 消息记录列表
     */
    async getRecordsByActivityId(activityId) {
        return await messageRecordModel_1.MessageRecord.find({ activityId }).sort({ createdAt: -1 });
    }
    /**
     * 根据ID获取单个消息推送记录
     * @param recordId 消息记录ID
     * @returns 消息记录对象或null
     */
    async getSingleRecord(recordId) {
        return await messageRecordModel_1.MessageRecord.findById(recordId);
    }
    /**
     * 更新消息推送记录的状态，常用于更新推送状态
     * @param recordId 消息记录ID
     * @param updateData 更新数据
     * @returns 更新后的消息记录对象
     */
    async updateMessageRecord(recordId, updateData) {
        return await messageRecordModel_1.MessageRecord.findByIdAndUpdate(recordId, updateData, { new: true });
    }
    /**
     * 获取整体消息推送统计数据
     */
    async getOverallStatistics() {
        try {
            const result = await messageRecordModel_1.MessageRecord.aggregate([
                // 1. 按状态和inforeground字段分组，计算每个类别的记录数
                {
                    $group: {
                        _id: { status: "$status", inforeground: "$inforeground" },
                        count: { $sum: 1 },
                    },
                },
                // 2. 将数据重组，计算总数、发送成功数、送达数、打开数、展示数
                {
                    $group: {
                        _id: null,
                        totalRecords: { $sum: "$count" },
                        // 发送成功数：status >= 1
                        sent: {
                            $sum: { $cond: [{ $gte: ["$_id.status", 1] }, "$count", 0] },
                        },
                        // 送达数：status >= 2
                        delivered: {
                            $sum: { $cond: [{ $gte: ["$_id.status", 2] }, "$count", 0] },
                        },
                        // 打开数：status === 3
                        opened: {
                            $sum: { $cond: [{ $eq: ["$_id.status", 3] }, "$count", 0] },
                        },
                        failed: {
                            $sum: { $cond: [{ $eq: ["$_id.status", -1] }, "$count", 0] },
                        },
                        // 展示数：status >= 2 并且 inforeground = false
                        displayCount: {
                            $sum: {
                                $cond: [
                                    {
                                        $and: [{ $gte: ["$_id.status", 2] }, { $eq: ["$_id.inforeground", false] }],
                                    },
                                    "$count",
                                    0,
                                ],
                            },
                        },
                    },
                },
                // 3. 计算比率并格式化输出
                {
                    $project: {
                        _id: 0,
                        totalRecords: "$totalRecords",
                        sent: "$sent",
                        delivered: "$delivered",
                        opened: "$opened",
                        failed: "$failed",
                        displayCount: "$displayCount",
                        // 发送成功率 = sent / totalRecords
                        sentSuccessRate: {
                            $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$sent", "$totalRecords"] }],
                        },
                        // 送达率 = delivered / sent
                        deliveredRate: {
                            $cond: [{ $eq: ["$sent", 0] }, 0, { $divide: ["$delivered", "$sent"] }],
                        },
                        // 展示率 = displayCount / delivered
                        displayRate: {
                            $cond: [{ $eq: ["$delivered", 0] }, 0, { $divide: ["$displayCount", "$delivered"] }],
                        },
                        // 点击率 = opened / displayCount
                        clickThroughRate: {
                            $cond: [{ $eq: ["$displayCount", 0] }, 0, { $divide: ["$opened", "$displayCount"] }],
                        },
                        // Token 失效率 = failed / totalRecords
                        tokenInvalidationRate: {
                            $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$failed", "$totalRecords"] }],
                        },
                    },
                },
            ]);
            return result[0];
        }
        catch (error) {
            console.error("Error fetching overall statistics:", error);
            return null;
        }
    }
    /**
     * 按活动获取消息统计数据
     */
    async getStatisticsByActivity() {
        try {
            const results = await messageRecordModel_1.MessageRecord.aggregate([
                // 1. 根据 activityId, status, 和 inforeground 进行分组
                {
                    $group: {
                        _id: {
                            activityId: "$activityId",
                            activityName: "$activityName",
                            status: "$status",
                            inforeground: "$inforeground",
                        },
                        count: { $sum: 1 },
                    },
                },
                // 2. 将数据重组，以便按 activityId 汇总
                {
                    $group: {
                        _id: "$_id.activityId",
                        activityName: { $first: "$_id.activityName" },
                        totalRecords: { $sum: "$count" },
                        // 发送成功数：status >= 1
                        sent: {
                            $sum: { $cond: [{ $gte: ["$_id.status", 1] }, "$count", 0] },
                        },
                        // 送达数：status >= 2
                        delivered: {
                            $sum: { $cond: [{ $gte: ["$_id.status", 2] }, "$count", 0] },
                        },
                        // 打开数：status === 3
                        opened: {
                            $sum: { $cond: [{ $eq: ["$_id.status", 3] }, "$count", 0] },
                        },
                        failed: {
                            $sum: { $cond: [{ $eq: ["$_id.status", -1] }, "$count", 0] },
                        },
                        // 展示数：status >= 2 并且 inforeground = false
                        displayCount: {
                            $sum: {
                                $cond: [
                                    {
                                        $and: [{ $gte: ["$_id.status", 2] }, { $eq: ["$_id.inforeground", false] }],
                                    },
                                    "$count",
                                    0,
                                ],
                            },
                        },
                    },
                },
                // 3. 计算比率并格式化输出
                {
                    $project: {
                        _id: 0,
                        activityId: "$_id",
                        activityName: "$activityName",
                        totalRecords: "$totalRecords",
                        sent: "$sent",
                        delivered: "$delivered",
                        opened: "$opened",
                        failed: "$failed",
                        displayCount: "$displayCount",
                        // 发送成功率 = sent / totalRecords
                        sentSuccessRate: {
                            $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$sent", "$totalRecords"] }],
                        },
                        // 送达率 = delivered / sent
                        deliveredRate: {
                            $cond: [{ $eq: ["$sent", 0] }, 0, { $divide: ["$delivered", "$sent"] }],
                        },
                        // 展示率 = displayCount / delivered
                        displayRate: {
                            $cond: [{ $eq: ["$delivered", 0] }, 0, { $divide: ["$displayCount", "$delivered"] }],
                        },
                        // 点击率 = opened / displayCount
                        clickThroughRate: {
                            $cond: [{ $eq: ["$displayCount", 0] }, 0, { $divide: ["$opened", "$displayCount"] }],
                        },
                        // Token 失效率 = failed / totalRecords
                        tokenInvalidationRate: {
                            $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$failed", "$totalRecords"] }],
                        },
                    },
                },
                // 4. (可选) 按 deliveredRate 降序排序
                {
                    $sort: { deliveredRate: -1 },
                },
            ]);
            return results;
        }
        catch (error) {
            console.error("Error fetching statistics by activity:", error);
            return [];
        }
    }
    /**
     * 按策略获取消息统计数据
     */
    async getStatisticsByStrategy() {
        try {
            const results = await messageRecordModel_1.MessageRecord.aggregate([
                // 1. 根据 strategyId, status, 和 inforeground 进行分组
                {
                    $group: {
                        _id: {
                            strategyId: "$strategyId",
                            strategyName: "$strategyName",
                            status: "$status",
                            inforeground: "$inforeground",
                        },
                        count: { $sum: 1 },
                    },
                },
                // 2. 将数据重组，以便按 strategyId 汇总
                {
                    $group: {
                        _id: "$_id.strategyId",
                        strategyName: { $first: "$_id.strategyName" },
                        totalRecords: { $sum: "$count" },
                        // 发送成功数：status >= 1
                        sent: {
                            $sum: { $cond: [{ $gte: ["$_id.status", 1] }, "$count", 0] },
                        },
                        // 送达数：status >= 2
                        delivered: {
                            $sum: { $cond: [{ $gte: ["$_id.status", 2] }, "$count", 0] },
                        },
                        // 打开数：status === 3
                        opened: {
                            $sum: { $cond: [{ $eq: ["$_id.status", 3] }, "$count", 0] },
                        },
                        failed: {
                            $sum: { $cond: [{ $eq: ["$_id.status", -1] }, "$count", 0] },
                        },
                        // 展示数：status >= 2 并且 inforeground = false
                        displayCount: {
                            $sum: {
                                $cond: [
                                    {
                                        $and: [{ $gte: ["$_id.status", 2] }, { $eq: ["$_id.inforeground", false] }],
                                    },
                                    "$count",
                                    0,
                                ],
                            },
                        },
                    },
                },
                // 3. 计算比率并格式化输出
                {
                    $project: {
                        _id: 0,
                        strategyId: "$_id",
                        strategyName: "$strategyName",
                        totalRecords: "$totalRecords",
                        sent: "$sent",
                        delivered: "$delivered",
                        opened: "$opened",
                        failed: "$failed",
                        displayCount: "$displayCount",
                        // 发送成功率 = sent / totalRecords
                        sentSuccessRate: {
                            $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$sent", "$totalRecords"] }],
                        },
                        // 送达率 = delivered / sent
                        deliveredRate: {
                            $cond: [{ $eq: ["$sent", 0] }, 0, { $divide: ["$delivered", "$sent"] }],
                        },
                        // 展示率 = displayCount / delivered
                        displayRate: {
                            $cond: [{ $eq: ["$delivered", 0] }, 0, { $divide: ["$displayCount", "$delivered"] }],
                        },
                        // 点击率 = opened / displayCount
                        clickThroughRate: {
                            $cond: [{ $eq: ["$displayCount", 0] }, 0, { $divide: ["$opened", "$displayCount"] }],
                        },
                        // Token 失效率 = failed / totalRecords
                        tokenInvalidationRate: {
                            $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$failed", "$totalRecords"] }],
                        },
                    },
                },
                // 4. (可选) 按 deliveredRate 降序排序
                {
                    $sort: { deliveredRate: -1 },
                },
            ]);
            return results;
        }
        catch (error) {
            console.error("Error fetching statistics by strategy:", error);
            return [];
        }
    }
    /**
     * 按模板获取消息统计数据
     */
    async getStatisticsByTemplate() {
        try {
            const results = await messageRecordModel_1.MessageRecord.aggregate([
                // 1. 根据 templateId, status, 和 inforeground 进行分组
                {
                    $group: {
                        _id: {
                            templateId: "$templateId",
                            templateName: "$templateName",
                            status: "$status",
                            inforeground: "$inforeground",
                        },
                        count: { $sum: 1 },
                    },
                },
                // 2. 将数据重组，以便按 templateId 汇总
                {
                    $group: {
                        _id: "$_id.templateId",
                        templateName: { $first: "$_id.templateName" },
                        totalRecords: { $sum: "$count" },
                        // 发送成功数：status >= 1
                        sent: {
                            $sum: { $cond: [{ $gte: ["$_id.status", 1] }, "$count", 0] },
                        },
                        // 送达数：status >= 2
                        delivered: {
                            $sum: { $cond: [{ $gte: ["$_id.status", 2] }, "$count", 0] },
                        },
                        // 打开数：status === 3
                        opened: {
                            $sum: { $cond: [{ $eq: ["$_id.status", 3] }, "$count", 0] },
                        },
                        failed: {
                            $sum: { $cond: [{ $eq: ["$_id.status", -1] }, "$count", 0] },
                        },
                        // 展示数：status >= 2 并且 inforeground = false
                        displayCount: {
                            $sum: {
                                $cond: [
                                    {
                                        $and: [{ $gte: ["$_id.status", 2] }, { $eq: ["$_id.inforeground", false] }],
                                    },
                                    "$count",
                                    0,
                                ],
                            },
                        },
                    },
                },
                // 3. 计算比率并格式化输出
                {
                    $project: {
                        _id: 0,
                        templateId: "$_id",
                        templateName: "$templateName",
                        totalRecords: "$totalRecords",
                        sent: "$sent",
                        delivered: "$delivered",
                        opened: "$opened",
                        failed: "$failed",
                        displayCount: "$displayCount",
                        // 发送成功率 = sent / totalRecords
                        sentSuccessRate: {
                            $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$sent", "$totalRecords"] }],
                        },
                        // 送达率 = delivered / sent
                        deliveredRate: {
                            $cond: [{ $eq: ["$sent", 0] }, 0, { $divide: ["$delivered", "$sent"] }],
                        },
                        // 展示率 = displayCount / delivered
                        displayRate: {
                            $cond: [{ $eq: ["$delivered", 0] }, 0, { $divide: ["$displayCount", "$delivered"] }],
                        },
                        // 点击率 = opened / displayCount
                        clickThroughRate: {
                            $cond: [{ $eq: ["$displayCount", 0] }, 0, { $divide: ["$opened", "$displayCount"] }],
                        },
                        // Token 失效率 = failed / totalRecords
                        tokenInvalidationRate: {
                            $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$failed", "$totalRecords"] }],
                        },
                    },
                },
                // 4. (可选) 按 deliveredRate 降序排序
                {
                    $sort: { deliveredRate: -1 },
                },
            ]);
            return results;
        }
        catch (error) {
            console.error("Error fetching statistics by template:", error);
            return [];
        }
    }
    // 按时间维度的趋势分析，每日统计
    async getDailySentTrends() {
        try {
            const results = await messageRecordModel_1.MessageRecord.aggregate([
                // 1. 将 actualSendAt 字段转换为日期，忽略时分秒
                {
                    $project: {
                        _id: 0,
                        date: {
                            $dateTrunc: { date: "$actualSendAt", unit: "day", timezone: "America/Los_Angeles" },
                        },
                        status: "$status",
                        inforeground: "$inforeground",
                    },
                },
                // 2. 根据日期、状态和 inforeground 进行分组
                {
                    $group: {
                        _id: { date: "$date", status: "$status", inforeground: "$inforeground" },
                        count: { $sum: 1 },
                    },
                },
                // 3. 将数据重组，以便按日期汇总
                {
                    $group: {
                        _id: "$_id.date",
                        totalRecords: { $sum: "$count" },
                        // 发送成功数：status >= 1
                        sent: {
                            $sum: { $cond: [{ $gte: ["$_id.status", 1] }, "$count", 0] },
                        },
                        // 送达数：status >= 2
                        delivered: {
                            $sum: { $cond: [{ $gte: ["$_id.status", 2] }, "$count", 0] },
                        },
                        // 打开数：status === 3
                        opened: {
                            $sum: { $cond: [{ $eq: ["$_id.status", 3] }, "$count", 0] },
                        },
                        failed: {
                            $sum: { $cond: [{ $eq: ["$_id.status", -1] }, "$count", 0] },
                        },
                        // 展示数：status >= 2 并且 inforeground = false
                        displayCount: {
                            $sum: {
                                $cond: [
                                    {
                                        $and: [{ $gte: ["$_id.status", 2] }, { $eq: ["$_id.inforeground", false] }],
                                    },
                                    "$count",
                                    0,
                                ],
                            },
                        },
                    },
                },
                // 4. 计算比率并格式化输出
                {
                    $project: {
                        _id: 0,
                        date: "$_id",
                        totalRecords: "$totalRecords",
                        sent: "$sent",
                        delivered: "$delivered",
                        opened: "$opened",
                        failed: "$failed",
                        displayCount: "$displayCount",
                        // 发送成功率 = sent / totalRecords
                        sentSuccessRate: {
                            $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$sent", "$totalRecords"] }],
                        },
                        // 送达率 = delivered / sent
                        deliveredRate: {
                            $cond: [{ $eq: ["$sent", 0] }, 0, { $divide: ["$delivered", "$sent"] }],
                        },
                        // 展示率 = displayCount / delivered
                        displayRate: {
                            $cond: [{ $eq: ["$delivered", 0] }, 0, { $divide: ["$displayCount", "$delivered"] }],
                        },
                        // 点击率 = opened / displayCount
                        clickThroughRate: {
                            $cond: [{ $eq: ["$displayCount", 0] }, 0, { $divide: ["$opened", "$displayCount"] }],
                        },
                        // Token invalidation rate
                        tokenInvalidationRate: {
                            $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$failed", "$totalRecords"] }],
                        },
                    },
                },
                // 5. 按日期升序排序
                {
                    $sort: { date: 1 },
                },
            ]);
            return results;
        }
        catch (error) {
            console.error("Error fetching daily sent trends:", error);
            return [];
        }
    }
    // 消息生命周期分析
    async getAverageDeliveryTime() {
        try {
            const result = await messageRecordModel_1.MessageRecord.aggregate([
                // 1. 只筛选出已送达的消息（status >= 2）
                {
                    $match: {
                        status: { $gte: 2 },
                        actualSendAt: { $exists: true, $ne: null },
                        deliveredAt: { $exists: true, $ne: null },
                    },
                },
                // 2. 计算每条消息的发送到送达的时间差（毫秒）
                {
                    $addFields: {
                        time_to_deliver: {
                            $subtract: ["$deliveredAt", "$actualSendAt"],
                        },
                    },
                },
                // 3. 计算平均时间
                {
                    $group: {
                        _id: null,
                        avg_time_to_deliver_ms: { $avg: "$time_to_deliver" },
                    },
                },
                // 4. 转换成秒或分钟以方便阅读
                {
                    $project: {
                        _id: 0,
                        averageTimeToDeliverInSeconds: {
                            $divide: ["$avg_time_to_deliver_ms", 1000],
                        },
                    },
                },
            ]);
            return result[0];
        }
        catch (error) {
            console.error("Error calculating average delivery time:", error);
            return null;
        }
    }
}
exports.MessageRecordService = MessageRecordService;
