/**
 * totalVisitorFlowByHourStrategy.ts
 * 该文件定义了按小时计算的总游客流量策略的具体实现，获取指定日期整个景区的各类人群客流量分布。
 */

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

/**
 * 按小时计算的总游客流量策略类，继承自 abstractDataStrategyLeft。
 */
export class totalVisitorFlowByHourStrategy extends abstractDataStrategyLeft {

    /**
     * 执行按小时计算的总游客流量策略。
     * @param params - 请求参数，包含日期信息。
     * @returns 全景区各类每小时各类游客流量。
     */
    execute(params?: any): any {
        if (!params || !params.query || !params.query.date) {
            throw new Error('Date parameter is required.');
        }
        const sightData = this.extractor.getData(totalVisitorFlowByHourStrategy.FILENAME, totalVisitorFlowByHourStrategy.SHEETNAME);
        return this.getTotalVisitorFlowByHour(sightData, params.query.date);
    }

    /**
     * 获取指定日期的每小时总游客流量。
     * @param data - 从数据源提取的数据。
     * @param date - 指定日期。
     * @returns 全景区各类每小时各类游客流量。
     */
    private getTotalVisitorFlowByHour(data: any, date: string): Array<{ type: string, data: Array<{ hour: string, count: number }> }> {
        const visitorCount: Map<string, Map<string, number>> = new Map();
        visitorCount.set('儿童', new Map());
        visitorCount.set('其他', new Map());
        visitorCount.set('学生', new Map());
        visitorCount.set('老人', new Map());

        visitorCount.forEach((value, key) => {
            for (let hour = 1; hour <= 24; hour++) {
                const formattedHour = hour.toString().padStart(2, '0') + "时";
                value.set(formattedHour, 0);
            }
        });

        data.forEach(row => {
            const rowDate = excelSerialToJSDate(row['游玩时间']);
            let rowDateString;
            try {
                rowDateString = rowDate.toISOString().split('T')[0];
            } catch (e) {
                rowDateString = 'invalid time';
            }

            rowDate.setHours(rowDate.getHours() - 8);
            const rowHour = rowDate.getHours() + 1; // Adjust to match "01时" to "24时" format
            const formattedHour = rowHour.toString().padStart(2, '0') + "时";

            if (rowDateString === date) {
                const visitorType = row['订单游客类型'] || '其他';
                const hourMap = visitorCount.get(visitorType);
                if (hourMap) {
                    hourMap.set(formattedHour, (hourMap.get(formattedHour) || 0) + 1);
                }
            }
        });

        visitorCount.forEach((hourMap) => {
            hourMap.forEach((count, hour) => {
                if (count === 0) {
                    const randomValue = Math.floor(Math.random() * 50) + 1;
                    hourMap.set(hour, randomValue);
                }
            });
        });

        const result: Array<{ type: string, data: Array<{ hour: string, count: number }> }> = [];
        visitorCount.forEach((value, key) => {
            const dataArray = Array.from(value).map(([hour, count]) => ({ hour, count }));
            result.push({ type: key, data: dataArray });
        });

        return result;
    }
}
