"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();
    }
    /**
     * 分页获取消息推送记录，支持筛选和排序
     */
    async getPaginatedRecords(page = MessageRecordService.DEFAULT_PAGE, limit = MessageRecordService.DEFAULT_LIMIT, filters = {}, sortField = MessageRecordService.DEFAULT_SORT_FIELD, sortOrder = MessageRecordService.DEFAULT_SORT_ORDER) {
        // 构建查询条件
        const query = this.buildDateFilterQuery(filters);
        // 添加非日期筛选条件
        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 sortOption = {};
        sortOption[sortField] = sortOrder === "asc" ? 1 : -1;
        const total = await messageRecordModel_1.MessageRecord.countDocuments(query);
        const records = await messageRecordModel_1.MessageRecord.find(query)
            .sort(sortOption)
            .skip((page - 1) * limit)
            .limit(limit);
        const totalPages = Math.ceil(total / limit);
        return { records, total, page, limit, totalPages };
    }
    /**
     * 根据用户UID获取其所有消息推送记录
     */
    async getRecordsByUid(uid) {
        return await messageRecordModel_1.MessageRecord.find({ uid }).sort({ createdAt: -1 });
    }
    /**
     * 根据消息活动ID获取所有相关的推送记录
     */
    async getRecordsByActivityId(activityId) {
        return await messageRecordModel_1.MessageRecord.find({ activityId }).sort({ createdAt: -1 });
    }
    /**
     * 根据ID获取单个消息推送记录
     */
    async getSingleRecord(recordId) {
        return await messageRecordModel_1.MessageRecord.findById(recordId);
    }
    /**
     * 更新消息推送记录的状态
     */
    async updateMessageRecord(recordId, updateData) {
        return await messageRecordModel_1.MessageRecord.findByIdAndUpdate(recordId, updateData, { new: true });
    }
    /**
     * 获取整体消息推送统计数据（含用户点击率）
     */
    async getOverallStatistics(startDate, endDate, strategyName) {
        const matchConditions = this.buildMatchConditions(startDate, endDate, strategyName);
        return this.getStatisticsByGroup(matchConditions, []);
    }
    /**
     * 按活动获取消息统计数据（含用户点击率）
     */
    async getStatisticsByActivity(startDate, endDate) {
        const matchConditions = this.buildMatchConditions(startDate, endDate);
        const groupFields = ["activityId", "activityName"];
        return this.getStatisticsByGroup(matchConditions, groupFields, { deliveredRate: -1 });
    }
    /**
     * 按策略获取消息统计数据（含用户点击率）
     */
    async getStatisticsByStrategy(startDate, endDate, strategyName) {
        const matchConditions = this.buildMatchConditions(startDate, endDate, strategyName);
        const groupFields = ["strategyId", "strategyName"];
        return this.getStatisticsByGroup(matchConditions, groupFields, { clickThroughRate: -1 });
    }
    /**
     * 按模板获取消息统计数据（含用户点击率）
     */
    async getStatisticsByTemplate(startDate, endDate, strategyName) {
        const matchConditions = this.buildMatchConditions(startDate, endDate, strategyName);
        const groupFields = ["templateId", "templateName"];
        return this.getStatisticsByGroup(matchConditions, groupFields, { clickThroughRate: -1 });
    }
    /**
     * 按国家代码获取消息统计数据（含用户点击率）
     */
    async getStatisticsByCc(startDate, endDate, strategyName) {
        const matchConditions = this.buildMatchConditions(startDate, endDate, strategyName);
        const groupFields = ["cc"];
        return this.getStatisticsByGroup(matchConditions, groupFields, { totalRecords: -1 });
    }
    /**
     * 按图片 URL 获取消息统计数据（含用户点击率）
     */
    async getStatisticsByImage(startDate, endDate, strategyName) {
        const matchConditions = this.buildMatchConditions(startDate, endDate, strategyName);
        const groupFields = ["image"];
        return this.getStatisticsByGroup(matchConditions, groupFields, { clickThroughRate: -1 });
    }
    /**
     * 按时间维度的趋势分析，每日统计（含用户点击率）
     */
    async getDailySentTrends(startDate, endDate, strategyName) {
        return this.getDailyTrendsByDimensions(startDate, endDate, strategyName, []);
    }
    /**
     * 按国家代码和时间维度获取每日统计数据（含用户点击率）
     */
    async getDailyTrendsByCc(cc, startDate, endDate, strategyName) {
        return this.getDailyTrendsByDimensions(startDate, endDate, strategyName, [{ cc }]);
    }
    /**
     * 按策略名称和时间维度获取每日统计数据（含用户点击率）
     */
    async getDailyTrendsByStrategy(strategyName, startDate, endDate) {
        return this.getDailyTrendsByDimensions(startDate, endDate, strategyName, [{ strategyName }]);
    }
    /**
     * 按模板ID和时间维度获取每日统计数据（含用户点击率）
     */
    async getDailyTrendsByTemplate(templateName, startDate, endDate, strategyName) {
        return this.getDailyTrendsByDimensions(startDate, endDate, strategyName, [{ templateName }]);
    }
    /**
     * 按图片URL和时间维度获取每日统计数据（含用户点击率）
     */
    async getDailyTrendsByImage(image, startDate, endDate, strategyName) {
        return this.getDailyTrendsByDimensions(startDate, endDate, strategyName, [{ image }]);
    }
    /**
     * 按多个维度获取消息推送统计数据（含用户点击率）
     */
    async getMultiDimensionalStatistics(filters) {
        try {
            const pipeline = [];
            // 构建匹配阶段
            const matchStage = this.buildMatchConditions(filters.startDate, filters.endDate, filters.strategyName);
            // 添加额外筛选条件
            if (filters.templateName)
                matchStage.templateName = filters.templateName;
            if (filters.cc)
                matchStage.cc = filters.cc;
            if (filters.image)
                matchStage.image = filters.image;
            if (Object.keys(matchStage).length > 0) {
                pipeline.push({ $match: matchStage });
            }
            // 构建分组阶段 - 收集唯一用户ID（按uid去重）
            pipeline.push({
                $group: {
                    _id: {
                        date: { $dateTrunc: { date: "$createdAt", unit: "day", timezone: MessageRecordService.TIMEZONE } },
                        templateName: "$templateName",
                        strategyName: "$strategyName",
                        cc: "$cc",
                        image: "$image",
                        status: "$status",
                        inforeground: "$inforeground",
                    },
                    count: { $sum: 1 }, // 人次统计（原逻辑保留）
                    uniqueUids: { $addToSet: "$uid" }, // 收集该分组下的唯一用户ID（去重）
                },
            });
            // 汇总阶段 - 计算人数统计
            pipeline.push({
                $group: {
                    _id: {
                        date: "$_id.date",
                        templateName: "$_id.templateName",
                        strategyName: "$_id.strategyName",
                        cc: "$_id.cc",
                        image: "$_id.image",
                    },
                    totalRecords: { $sum: "$count" },
                    ...this.getStatusAggregationFields(), // 包含人次+人数统计
                },
            });
            // 计算比率并格式化输出（含用户点击率）
            pipeline.push({
                $project: this.getStatisticsProjectFields(["date", "templateName", "strategyName", "cc", "image"]),
            });
            // 排序
            pipeline.push({
                $sort: { date: 1, templateName: 1, cc: 1, image: 1 },
            });
            return await messageRecordModel_1.MessageRecord.aggregate(pipeline);
        }
        catch (error) {
            console.error("Error fetching multi-dimensional statistics:", error);
            return [];
        }
    }
    // ------------------------------
    // 私有工具方法 - 提取公共逻辑
    // ------------------------------
    /**
     * 构建日期筛选查询条件
     */
    buildDateFilterQuery(filters) {
        const query = {};
        // 处理所有日期字段的筛选
        ["createdAt", "sentAt", "displayedAt", "openedAt"].forEach((field) => {
            if (filters[field]) {
                const dates = filters[field].split(",");
                const startDate = new Date(dates[0]);
                if (dates.length > 1) {
                    const endDate = new Date(dates[1]);
                    query[field] = { $gte: startDate, $lte: endDate };
                }
                else {
                    query[field] = { $gte: startDate };
                }
            }
        });
        return query;
    }
    /**
     * 构建匹配条件
     */
    buildMatchConditions(startDate, endDate, strategyName) {
        const conditions = {};
        // 处理日期范围
        if (startDate || endDate) {
            conditions.createdAt = {};
            if (startDate) {
                conditions.createdAt.$gte = startDate;
            }
            if (endDate) {
                // 容错处理：如果 endDate <= startDate，将 endDate 设为 startDate 的后一天
                if (startDate && endDate.getTime() <= startDate.getTime()) {
                    endDate = new Date(startDate.getTime() + 24 * 60 * 60 * 1000);
                }
                conditions.createdAt.$lte = endDate;
            }
        }
        // 处理策略名称筛选
        if (strategyName) {
            conditions.strategyName = strategyName;
        }
        return conditions;
    }
    /**
     * 获取状态聚合字段（含人次和人数统计）
     */
    getStatusAggregationFields() {
        return {
            // 1. 原有人次统计（保留）
            sent: { $sum: { $cond: [{ $gte: ["$_id.status", 1] }, "$count", 0] } },
            delivered: { $sum: { $cond: [{ $gte: ["$_id.status", 2] }, "$count", 0] } },
            opened: { $sum: { $cond: [{ $eq: ["$_id.status", 3] }, "$count", 0] } },
            failed: { $sum: { $cond: [{ $eq: ["$_id.status", -1] }, "$count", 0] } },
            displayCount: {
                $sum: {
                    $cond: [{ $and: [{ $gte: ["$_id.status", 2] }, { $eq: ["$_id.inforeground", false] }] }, "$count", 0],
                },
            },
            // 2. 新增：按uid去重的人数统计
            displayedUsers: {
                // 展示人数：至少被展示1次的独立用户数
                $sum: {
                    $cond: [
                        { $and: [{ $gte: ["$_id.status", 2] }, { $eq: ["$_id.inforeground", false] }] },
                        { $size: "$uniqueUids" }, // 计算去重后的用户数
                        0,
                    ],
                },
            },
            openedUsers: {
                // 点击人数：至少点击1次的独立用户数
                $sum: {
                    $cond: [{ $eq: ["$_id.status", 3] }, { $size: "$uniqueUids" }, 0],
                },
            },
        };
    }
    /**
     * 获取统计结果投影字段（含用户点击率）
     */
    getStatisticsProjectFields(idFields) {
        const project = { _id: 0 };
        // 显式处理date字段
        if (idFields.includes("date")) {
            project.date = "$_id.date";
        }
        // 添加其他ID字段映射
        idFields.forEach((field) => {
            if (field !== "date") {
                project[field] = `$_id.${field}`;
            }
        });
        // 统计字段：包含原有人次指标 + 新增人数指标 + 用户点击率
        return {
            ...project,
            // 原有人次指标
            totalRecords: "$totalRecords",
            sent: "$sent",
            delivered: "$delivered",
            opened: "$opened",
            failed: "$failed",
            displayCount: "$displayCount",
            // 新增：人数指标
            displayedUsers: "$displayedUsers",
            openedUsers: "$openedUsers",
            // 原有比率指标
            sentSuccessRate: {
                $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$sent", "$totalRecords"] }],
            },
            deliveredRate: {
                $cond: [{ $eq: ["$sent", 0] }, 0, { $divide: ["$delivered", "$sent"] }],
            },
            displayRate: {
                $cond: [{ $eq: ["$delivered", 0] }, 0, { $divide: ["$displayCount", "$delivered"] }],
            },
            clickThroughRate: {
                // 原点击率（人次维度）
                $cond: [{ $eq: ["$displayCount", 0] }, 0, { $divide: ["$opened", "$displayCount"] }],
            },
            tokenInvalidationRate: {
                $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$failed", "$totalRecords"] }],
            },
            // 新增：用户点击率（人数维度）
            actualClickThroughRate: {
                $cond: [
                    { $eq: ["$displayedUsers", 0] }, // 避免除以0
                    0,
                    { $divide: ["$openedUsers", "$displayedUsers"] }, // 点击人数 / 展示人数
                ],
            },
        };
    }
    /**
     * 按分组获取统计数据的通用方法（支持用户点击率）
     */
    async getStatisticsByGroup(matchConditions, groupFields = [], sortOrder = { _id: 1 }) {
        try {
            const pipeline = [];
            // 添加匹配阶段
            if (Object.keys(matchConditions).length > 0) {
                pipeline.push({ $match: matchConditions });
            }
            // 构建分组键
            const groupId = {};
            groupFields.forEach((field) => {
                groupId[field] = `$${field}`;
            });
            groupId.status = "$status";
            groupId.inforeground = "$inforeground";
            // 第一阶段分组 - 收集唯一用户ID
            pipeline.push({
                $group: {
                    _id: groupId,
                    count: { $sum: 1 }, // 人次统计
                    uniqueUids: { $addToSet: "$uid" }, // 收集该分组下的唯一用户
                },
            });
            // 第二阶段分组 - 按主要维度汇总
            const mainGroupId = {};
            groupFields.forEach((field) => {
                mainGroupId[field] = `$_id.${field}`;
            });
            pipeline.push({
                $group: {
                    _id: mainGroupId,
                    ...groupFields.reduce((acc, field) => {
                        acc[field] = { $first: `$_id.${field}` };
                        return acc;
                    }, {}),
                    totalRecords: { $sum: "$count" },
                    ...this.getStatusAggregationFields(), // 包含人次+人数统计
                },
            });
            // 计算比率并格式化输出（含用户点击率）
            pipeline.push({
                $project: this.getStatisticsProjectFields(groupFields),
            });
            // 添加排序
            pipeline.push({ $sort: sortOrder });
            const results = await messageRecordModel_1.MessageRecord.aggregate(pipeline);
            return groupFields.length === 0 ? results[0] : results;
        }
        catch (error) {
            console.error("Error fetching statistics by group:", error);
            return groupFields.length === 0 ? null : [];
        }
    }
    /**
     * 按维度获取每日趋势的通用方法（支持用户点击率）
     */
    async getDailyTrendsByDimensions(startDate, endDate, strategyName, extraConditions = []) {
        try {
            const pipeline = [];
            // 构建匹配条件
            let matchConditions = this.buildMatchConditions(startDate, endDate, strategyName);
            // 添加额外条件
            extraConditions.forEach((cond) => {
                matchConditions = { ...matchConditions, ...cond };
            });
            pipeline.push({ $match: matchConditions });
            // 日期处理 - 明确创建date字段
            pipeline.push({
                $project: {
                    _id: 0,
                    date: {
                        $dateTrunc: { date: "$createdAt", unit: "day", timezone: MessageRecordService.TIMEZONE },
                    },
                    status: "$status",
                    inforeground: "$inforeground",
                    uid: "$uid", // 保留uid用于去重统计
                },
            });
            // 按日期、状态和前景标志分组 - 收集唯一用户
            pipeline.push({
                $group: {
                    _id: { date: "$date", status: "$status", inforeground: "$inforeground" },
                    count: { $sum: 1 }, // 人次统计
                    uniqueUids: { $addToSet: "$uid" }, // 收集该分组下的唯一用户
                },
            });
            // 按日期汇总 - 计算人数统计
            pipeline.push({
                $group: {
                    _id: "$_id.date",
                    date: { $first: "$_id.date" }, // 显式保留date字段
                    totalRecords: { $sum: "$count" },
                    ...this.getStatusAggregationFields(), // 包含人次+人数统计
                },
            });
            // 计算比率并格式化输出（含用户点击率）
            pipeline.push({
                $project: {
                    _id: 0,
                    date: "$date",
                    totalRecords: "$totalRecords",
                    sent: "$sent",
                    delivered: "$delivered",
                    opened: "$opened",
                    failed: "$failed",
                    displayCount: "$displayCount",
                    displayedUsers: "$displayedUsers",
                    openedUsers: "$openedUsers",
                    sentSuccessRate: {
                        $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$sent", "$totalRecords"] }],
                    },
                    deliveredRate: {
                        $cond: [{ $eq: ["$sent", 0] }, 0, { $divide: ["$delivered", "$sent"] }],
                    },
                    displayRate: {
                        $cond: [{ $eq: ["$delivered", 0] }, 0, { $divide: ["$displayCount", "$delivered"] }],
                    },
                    clickThroughRate: {
                        $cond: [{ $eq: ["$displayCount", 0] }, 0, { $divide: ["$opened", "$displayCount"] }],
                    },
                    tokenInvalidationRate: {
                        $cond: [{ $eq: ["$totalRecords", 0] }, 0, { $divide: ["$failed", "$totalRecords"] }],
                    },
                    actualClickThroughRate: {
                        $cond: [{ $eq: ["$displayedUsers", 0] }, 0, { $divide: ["$openedUsers", "$displayedUsers"] }],
                    },
                },
            });
            // 按日期排序
            pipeline.push({
                $sort: { date: -1 },
            });
            return await messageRecordModel_1.MessageRecord.aggregate(pipeline);
        }
        catch (error) {
            console.error("Error fetching daily trends:", error);
            return [];
        }
    }
}
exports.MessageRecordService = MessageRecordService;
// 提取常量便于维护
MessageRecordService.TIMEZONE = "America/Los_Angeles"; // UTC+8时区
// private static readonly TIMEZONE = "Asia/Shanghai"; // UTC+8时区
MessageRecordService.DEFAULT_PAGE = 1;
MessageRecordService.DEFAULT_LIMIT = 10;
MessageRecordService.DEFAULT_SORT_FIELD = "createdAt";
MessageRecordService.DEFAULT_SORT_ORDER = "desc";
