/**
 * allEventDataStrategy.ts
 * 该文件定义了所有事件数据策略的具体实现，获取所有事件并提取相关信息。
 */

import { abstractDataStrategyMid } from "./abstractDataStrategyMid";
import excelSerialToJSDate from "../../../util/excelDateToJSDate";

/**
 * 事件数据策略类，继承自 abstractDataStrategyMid。
 */
export class allEventDataStrategy extends abstractDataStrategyMid {
    static readonly RELEVANTINFO = ['事件标题', '处置状态', '事件类型', '事件子类型', '事件来源', '创建时间', '处置时间', '处置完成时间', '办结时间'];

    static readonly KEY_MAP = {
        '事件标题': 'eventTitle',
        '处置状态': 'dispositionStatus',
        '事件类型': 'eventType',
        '事件子类型': 'eventSubtype',
        '事件来源': 'eventSource',
        '创建时间': 'creationTime',
        '处置时间': 'dispositionTime',
        '处置完成时间': 'dispositionCompletionTime',
        '办结时间': 'closureTime'
    };

    /**
     * 执行所有事件数据策略。
     * @returns 事件的数据。
     */
    execute(): any {
        let eventData = this.extractor.getData(allEventDataStrategy.fileName, allEventDataStrategy.sheetName);
        this.removeUnusedColumns(eventData);
        return this.formatDataForFrontend(eventData);
    }

    /**
     * 移除数据中前端不使用的列
     * @param data - 从数据源提取的数据
     */
    private removeUnusedColumns(data: any) {
        data.forEach(row => {
            // Initialize missing relevant columns with a default value
            allEventDataStrategy.RELEVANTINFO.forEach(key => {
                if (!(key in row)) {
                    row[key] = null; // You can set this to any default value you prefer
                }
            });

            Object.keys(row).forEach(key => {
                if (!allEventDataStrategy.RELEVANTINFO.includes(key)) {
                    delete row[key];
                }
                if (typeof row[key] === 'number') {
                    row[key] = excelSerialToJSDate(row[key]);
                }
            });
        });
    }

    /**
     * 将键转换为英文，并格式化日期
     * @param data - 处理后的数据
     * @returns 格式化后的前端数据
     */
    private formatDataForFrontend(data: any): any {
        return data.map(row => {
            let formattedRow: { [key: string]: any } = {};
            Object.keys(row).forEach(key => {
                const translatedKey = allEventDataStrategy.KEY_MAP[key];
                let value = row[key];

                // Format date if key is one of the date fields
                if (['creationTime', 'dispositionTime', 'dispositionCompletionTime', 'closureTime'].includes(translatedKey) && value) {
                    value = new Date(value).toLocaleString('zh-CN', { hour12: false }).replace(/\//g, '-').replace(',', '');
                }

                // Only add non-null values to the formatted row
                if (value !== null) {
                    formattedRow[translatedKey] = value;
                }
            });

            // Add detail section with all time fields and their corresponding statuses
            formattedRow.detail = this.constructDetailSection(formattedRow);

            return formattedRow;
        });
    }

    /**
     * 构建详细信息部分
     * @param row - 事件数据行
     * @returns 详细信息部分
     */
    private constructDetailSection(row: { [key: string]: any }): any {
        const details: any = {};

        if (row.creationTime) {
            details.creationTime = {
                time: row.creationTime,
                status: '待调度'
            };
        }

        if (row.dispositionTime) {
            details.dispositionTime = {
                time: row.dispositionTime,
                status: '处置中'
            };
        }

        if (row.dispositionCompletionTime) {
            details.dispositionCompletionTime = {
                time: row.dispositionCompletionTime,
                status: '已处置'
            };
        }

        if (row.closureTime) {
            details.closureTime = {
                time: row.closureTime,
                status: '已办结'
            };
        }

        // Remove any null detail fields
        Object.keys(details).forEach(key => {
            if (details[key].time === null) {
                delete details[key];
            }
        });

        return Object.values(details);
    }
}
