/**
 * sightVisitorFlowByDayStrategy.ts
 * 该文件定义了按天计算的游客流量策略的具体实现。
 */

import { randomStatusGenerator } from "../../../../util/randomStatusGenerator";
import excelSerialToJSDate from "../../../../util/excelDateToJSDate";
import { abstractDataStrategyLeft } from "./abstractDataStrategyLeft";
import paramChecker from "../../../../util/paramChecker";

/**
 * 按天计算的游客流量策略类，继承自 abstractDataStrategyLeft。
 */
export class sightVisitorFlowByDayStrategy extends abstractDataStrategyLeft {
    /**
     * 执行按天计算的游客流量策略。
     * @param params - 请求参数，包含日期信息。
     * @returns 每小时的游客流量。
     */
    execute(params?: any): any {
        paramChecker.checkDateParam(params);
        let sightData = this.extractor.getData(sightVisitorFlowByDayStrategy.FILENAME, sightVisitorFlowByDayStrategy.SHEETNAME);
        return this.getVisitorFlowByDay(sightData, params.query.date);
    }

    /**
     * 获取指定日期所有景点的游客流量和景点状态。
     * @param data - 从数据源提取的数据。
     * @param date - 指定日期。
     * @returns 每小时的游客流量映射。
     */
    private getVisitorFlowByDay(data: any, date: string): Array<{ key: string, count: number, status: string }> {
        const visitorCount: Map<string, { count: number, status: string }> = new Map();
        data.forEach(row => {
            const rowDate = excelSerialToJSDate(row['游玩时间']);
            let rowDateString;
            try {
                rowDateString = rowDate.toISOString().split('T')[0];
            } catch (e) {
                rowDateString = 'invalid time';
            }
            const sight = row['景点名称'];
            if (!visitorCount.has(sight)) {
                visitorCount.set(sight, { count: 0, status: randomStatusGenerator.getRandomStatus() });
            }

            if (rowDateString === date) {
                const sightData = visitorCount.get(sight)!;
                sightData.count++;
                visitorCount.set(sight, sightData);
            }
        });

        // Check if all counts are zero and replace with random numbers if so
        let allCountsAreZero = true;
        visitorCount.forEach((value) => {
            if (value.count !== 0) {
                allCountsAreZero = false;
            }
        });

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

        const result: Array<{ key: string, count: number, status: string }> = [];
        visitorCount.forEach((value, key) => {
            result.push({ key, count: value.count, status: value.status });
        });

        return result;
    }
}
