/**
 * 企业消息通知
 */

import moment = require("moment");
import { OPERATIONALDATATYPE, TABLEID, TABLENAME } from "../config/enum/dbEnum";
import { operationalData, selectData } from "../data/operationalData";
import { getMySqlMs, randomId } from "../tools/system";
import { BizError } from "../util/bizError";
import { ERRORENUM } from "../config/enum/errorEnum";
import { MSGTYPE } from "../config/enum/enum";


/**
 * 获取企业通知列表
 */
export async function getNotificationList(eId: string) {
    // 查询消息表，获取所有给该企业或所有企业的消息
    const messageFields = ["msgId", "msgType", "msgTitle", "createTime", "effectiveTime", "msgContent", "eId", "isPop"];
    
    // 查询条件：eId包含该企业或eId为空数组（发给所有企业）
    const selectParam = {
        "%or%": [
            { eId: { "%like%": eId } }, // 包含该企业ID
            { eId: '[]' } // 发给所有企业
        ]
    };
    
    let messageList = await selectData(
        OPERATIONALDATATYPE.查询多个, 
        TABLENAME.企业消息通知表, 
        selectParam, 
        messageFields
    );
    
    // 过滤过期消息
    const currentTime = getMySqlMs();
    messageList = messageList.filter(message => 
        !message.effectiveTime || message.effectiveTime > currentTime
    );
    
    // 按创建时间排序
    messageList.sort((a, b) => 
        new Date(b.createTime).valueOf() - new Date(a.createTime).valueOf()
    );
    
    // 获取已读状态
    const readStatusFields = ["readId", "msgId", "eId", "readTime", "isRead"];
    const readStatusList = await selectData(
        OPERATIONALDATATYPE.查询多个,
        TABLENAME.企业消息已读状态表,
        { eId: eId },
        readStatusFields
    );
    
    // 创建已读状态映射
    const readStatusMap = new Map();
    readStatusList.forEach(status => {
        readStatusMap.set(status.msgId, status);
    });
    
    // 存储需要创建的未读记录
    const unreadRecordsToCreate = [];
    
    // 构建返回数据
    const dataList = messageList.map(message => {
        // 解析企业ID数组
        let eIdArray: string[] = [];
        if (message.eId) {
            try {
                eIdArray = JSON.parse(message.eId);
            } catch (error) {
                console.error('解析 eId 失败:', error);
            }
        }
        
        // 获取已读状态
        const readStatus = readStatusMap.get(message.msgId);
        let isRead = false;
        let readTime = null;
        let readId = null;
        
        if (readStatus) {
            // 如果已有记录，使用现有状态
            isRead = readStatus.isRead === 1;
            readTime = readStatus.readTime;
            readId = readStatus.readId;
        } else {
            // 如果没有记录，标记为未读，并准备创建记录
            isRead = false;
            readTime = null;
            readId = null; // 尚未创建，没有readId
            
            // 收集需要创建的未读记录
            unreadRecordsToCreate.push({
                msgId: message.msgId,
                readId: randomId(TABLEID.企业消息已读状态表),
                eId: eId,
                readTime: null,
                isRead: 0, // 0表示未读
                createTime: getMySqlMs() // 添加创建时间
            });
        }
        
        return {
            msgId: message.msgId,
            readId: readId,
            msgType: message.msgType,
            msgTitle: message.msgTitle,
            msgContent: message.msgContent,
            eId: eIdArray,
            isPop: message.isPop === 1,
            isRead: isRead,
            effectiveTime: message.effectiveTime ? moment(message.effectiveTime).format("YYYY-MM-DD HH:mm:ss") : null,
            readTime: readTime ? moment(readTime).format("YYYY-MM-DD HH:mm:ss") : null,
            createTime: moment(message.createTime).format("YYYY-MM-DD HH:mm:ss")
        };
    });
    
    // 批量创建未读记录（如果有需要创建的）
    if (unreadRecordsToCreate.length > 0) {
        try {
            // 这里需要实现批量插入数据的函数
            await createUnreadRecords(unreadRecordsToCreate);
        } catch (error) {
            console.error('创建未读记录失败:', error);
            // 这里可以根据需要决定是否抛出错误
        }
    }
    
    return { dataList };
}

/**
 * 批量创建未读记录
 */
async function createUnreadRecords(records: any[]) {
    // 批量插入未读记录
    for (const record of records) {
        await operationalData(
            OPERATIONALDATATYPE.增加,
            TABLENAME.企业消息已读状态表,
            record,
            {}
        );
    }
}


/**
 * 标记通知为已读
 */
export async function markNotificationAsRead(eId: string, msgId: string, readId:string) {
    // 先检查消息是否存在且对该企业可见
    const message = await selectData(
        OPERATIONALDATATYPE.查询单个,
        TABLENAME.企业消息通知表,
        { 
            msgId: msgId,
            readId: readId,
            "%or%": [
                { eId: { "%like%": `%"${eId}"%` } },
                { eId: '[]' }
            ]
        },
        ["msgId"]
    );
    
    if (!message) {
        throw new BizError(ERRORENUM.数据不存在);
    }
    
    // 检查是否已存在已读记录
    const existingRead = await selectData(
        OPERATIONALDATATYPE.查询单个,
        TABLENAME.企业消息已读状态表,
        { 
            msgId: msgId,
            readId: readId,
            eId: eId
        },
        ["readId"]
    );
    
    if (Object.keys(existingRead).length) {
        // 更新已存在记录
        const updateData = {
            isRead: 1,
            // isRead: 0,
            readTime: getMySqlMs()
        };
        
        await operationalData(
            OPERATIONALDATATYPE.修改, 
            TABLENAME.企业消息已读状态表, 
            updateData, 
            { readId: existingRead.readId }
        );
    } else {
        // 创建新的已读记录
        const readData = {
            readId: randomId(TABLEID.企业消息已读状态表),
            msgId: msgId,
            eId: eId,
            isRead: 1,
            // isRead: 0,
            readTime: getMySqlMs()
        };
        
        await operationalData(
            OPERATIONALDATATYPE.增加, 
            TABLENAME.企业消息已读状态表, 
            readData, 
            {}
        );
    }
    
    return { isSuccess: true };
}


/**
 * 批量标记通知为已读
 */
export async function markNotificationsAsRead(eId: string, msgIds: string[], readId:string) {
    for (const msgId of msgIds) {
        await markNotificationAsRead(eId, msgId, readId);
    }
    
    return { isSuccess: true };
}


/**
 * 获取弹窗消息
 */
export async function getPopupNotifications(eId: string) {
    // 先获取所有消息
    const result = await getNotificationList(eId);
    
    // 过滤出弹窗消息
    const popupMessages = result.dataList.filter(message => message.isPop);
    
    // 特殊处理季度填报提醒消息
    const processedMessages = await Promise.all(
        popupMessages.map(async (message) => {
            // 如果是季度填报提醒类型
            if (message.msgType === MSGTYPE.季度填报提醒) {
                // 获取上季度的时间
                const lastQuarter = getLastQuarter();
                
                // 替换模板变量
                const year = lastQuarter.year;
                const quarter = lastQuarter.quarter;
                // const quarterNames = ["第一季度", "第二季度", "第三季度", "第四季度"];
                const quarterNames = ["一", "二", "三", "四"];
                
                // 替换标题和内容中的模板变量
                let processedTitle = message.msgTitle;
                let processedContent = message.msgContent;
                
                if (processedTitle.includes("${year}") || processedTitle.includes("${quarter}")) {
                    processedTitle = processedTitle
                        .replace(/\${year}/g, year.toString())
                        .replace(/\${quarter}/g, quarter.toString());
                }
                
                if (processedContent.includes("${year}") || processedContent.includes("${quarter}")) {
                    processedContent = processedContent
                        .replace(/\${year}/g, year.toString())
                        .replace(/\${quarter}/g, quarterNames[quarter-1]);
                }
                
                // 检查是否是每季度1号
                const today = moment();
                const isFirstDayOfMonth = today.date() === 1;
                
                if (isFirstDayOfMonth) {
                    // 重置该消息对该企业的已读状态为未读
                    await resetNotificationReadStatus(eId, message.msgId);
                    
                    // 返回处理后的消息，标记为未读
                    return {
                        ...message,
                        msgTitle: processedTitle,
                        msgContent: processedContent,
                        isRead: false // 强制设置为未读
                    };
                }
                
                // 如果不是1号，返回处理后的消息（保持原有已读状态）
                return {
                    ...message,
                    msgTitle: processedTitle,
                    msgContent: processedContent
                };
            }
            
            // 其他类型的消息保持不变
            return message;
        })
    );
    
    // 过滤出未读的消息（包括被重置为未读的季度填报提醒）
    const unreadPopupMessages = processedMessages.filter(message => !message.isRead);
    
    return { dataList: unreadPopupMessages };
}


/**
 * 获取上一个季度
 */
function getLastQuarter(): { year: number; quarter: number } {
    const currentTime = moment();
    const currentYear = currentTime.year();
    const currentMonth = currentTime.month() + 1;
    
    let lastQuarter = 0;
    let lastQuarterYear = currentYear;
    
    if (currentMonth >= 1 && currentMonth <= 3) {
        lastQuarter = 4;
        lastQuarterYear = currentYear - 1;
    } else if (currentMonth >= 4 && currentMonth <= 6) {
        lastQuarter = 1;
    } else if (currentMonth >= 7 && currentMonth <= 9) {
        lastQuarter = 2;
    } else {
        lastQuarter = 3;
    }
    
    return { year: lastQuarterYear, quarter: lastQuarter };
}


/**
 * 重置消息的已读状态为未读
 */
async function resetNotificationReadStatus(eId: string, msgId: string) {
    // 检查是否已存在已读记录
    const existingRead = await selectData(
        OPERATIONALDATATYPE.查询单个,
        TABLENAME.企业消息已读状态表,
        { 
            msgId: msgId,
            eId: eId
        },
        ["readId"]
    );
    
    if (existingRead) {
        // 更新已存在记录为未读
        const updateData = {
            isRead: 0,
            readTime: null
        };
        
        await operationalData(
            OPERATIONALDATATYPE.修改, 
            TABLENAME.企业消息已读状态表, 
            updateData, 
            { readId: existingRead.readId }
        );
    } else {
        // 如果没有已读记录，创建一条未读记录（可选）
        // 通常不需要，因为默认就是未读状态
    }
    
    return { isSuccess: true };
}




