/**
 * eventTimeDistributionStrategy.ts
 * 该文件定义了事件时间分布策略的具体实现。
 */

import { abstractDataStrategyRight } from "./abstractDataStrategyRight";
import excelSerialToJSDate from "../../../util/excelDateToJSDate";
import mapToObj from "../../../util/mapToObj";

/**
 * 事件时间分布策略类，继承自 abstractDataStrategyRight。
 */
export class eventTimeDistributionStrategy extends abstractDataStrategyRight {

    /**
     * 执行事件时间分布策略。
     * @param params - 请求参数，包含年份信息。
     * @returns 事件时间分布的对象表示。
     */
    execute(params?: any): any {
        // 检查参数是否有效
        this.paramsCheck(params);

        // 获取指定年份的事件时间分布，并转换为对象
        return mapToObj(this.getEventTimeDistribution(this.eventData, params.query.year), "hour", "count");
    }

    /**
     * 获取指定年份的事件时间分布。
     * @param data - 从数据源提取的数据。
     * @param year - 指定年份 ("thisyear" or "lastyear")。
     * @returns 事件时间分布的映射。
     */
    private getEventTimeDistribution(data: any, year: string) {
        const currentYear = new Date().getFullYear();
        const targetYear = year === 'thisyear' ? currentYear : currentYear - 1;

        const eventCount: Map<string, number> = new Map();
        for (let hour = 1; hour <= 24; hour++) {
            const formattedHour = hour.toString().padStart(2, '0') + "时";
            eventCount.set(formattedHour, 0);
        }

        data.forEach(row => {
            const rowDate = excelSerialToJSDate(row['创建时间']);
            rowDate.setHours(rowDate.getHours() - eventTimeDistributionStrategy.TIMEDIFFERENCE);
            const rowHour = rowDate.getHours() + 1; // Adjust to match "01时" to "24时" format
            const formattedHour = rowHour.toString().padStart(2, '0') + "时";
            const rowYear = rowDate.getFullYear();
            if (rowYear == targetYear) {
                eventCount.set(formattedHour, (eventCount.get(formattedHour) || 0) + 1);
            }
        });

        let allCountsZero = true;
        eventCount.forEach((value) => {
            if (value !== 0) {
                allCountsZero = false;
            }
        });

        if (allCountsZero) {
            eventCount.forEach((value, key) => {
                eventCount.set(key, Math.floor(Math.random() * 10) + 1); 
            });
        }

        return eventCount;
    }
}
