/**
 * abstractDataStrategyRight.ts
 * 该文件定义了一个抽象类，用于右侧数据策略的基础实现。
 */

import { dataStrategy } from "../dataStrategy";
import { DataExtractor } from "../../../util/dataExtractor";
import excelSerialToJSDate from "../../../util/excelDateToJSDate";

/**
 * 抽象数据策略右侧类，所有右侧具体策略类都需要继承该抽象类。
 */
export abstract class abstractDataStrategyRight implements dataStrategy {
    extractor = DataExtractor.getInstance();
    static readonly FILENAME = '寿州古城.xlsx';
    static readonly SHEETNAME = '指挥调度系统';
    static readonly TIMEDIFFERENCE = 8;
    protected eventData;

    /**
     * 构造函数，读取 Excel 数据并初始化 eventData 属性。
     */
    constructor() {
        this.eventData = this.readDataFromExcel();
    }

    /**
     * 执行策略的方法，具体实现由子类提供。
     * @param params - 可选参数。
     */
    abstract execute(params?: any): any;

    /**
     * 参数检查方法，检查参数中是否包含年份信息。
     * @param params - 请求参数。
     * @throws 如果参数无效则抛出错误。
     */
    protected paramsCheck(params) {
        if (!params || !params.query || !params.query.year) {
            throw new Error('Year parameter is required.');
        }
    }

    /**
     * 从 Excel 文件中读取数据。
     * @returns 读取的数据。
     */
    protected readDataFromExcel() {
        return this.extractor.getData(abstractDataStrategyRight.FILENAME, abstractDataStrategyRight.SHEETNAME);
    }

    /**
     * 注册事件项，初始化事件计数映射。
     * @param list - 事件名称列表。
     * @returns 初始化的事件计数映射。
     */
    protected registerItems(list: string[]) {
        const eventCount: Map<string, number> = new Map();
        list.forEach(event => {
            eventCount.set(event, 0);
        });
        return eventCount;
    }

    /**
     * 统计事件列表中每个事件的数量。
     * @param list - 事件名称列表。
     * @param target - 目标事件名称。
     * @param data - 数据源。
     * @param year - 指定年份。
     * @returns 事件计数映射。
     */
    protected getListCount(list: string[], target: string, data: any, year: number) {
        const count = this.registerItems(list);
        data.forEach(row => {
            const rowDate = excelSerialToJSDate(row['创建时间']);
            const rowYear = rowDate.getFullYear();

            if (rowYear === year) {
                count.set(row[target], count.get(row[target]) + 1);
            }
        });
        return count;
    }
}
