/**
 * 埋点服务
 * 提供分享和下载打印事件的上报功能
 */

import { getAppUUID } from './uuid';

// 格式化时间为 yyyy-MM-dd HH:mm
function formatTime(date: Date = new Date()): string {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    return `${year}-${month}-${day} ${hours}:${minutes}`;
}

/**
 * 获取今天的日期字符串（yyyy-MM-dd）
 */
function getTodayString(): string {
    const date = new Date();
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
}

/**
 * 获取事件计数（当天该事件上报的次数）
 * 使用本地存储持久化，每天重置计数
 */
function getEventCount(eventName: string): number {
    try {
        const storageKey = `tracker_count_${eventName}`;
        const dateKey = `tracker_date_${eventName}`;
        const today = getTodayString();

        // 获取上次记录的日期
        const lastDate = wx.getStorageSync(dateKey);

        let currentCount = 0;
        // 如果是今天，获取上次的计数；否则重置为0
        if (lastDate === today) {
            currentCount = wx.getStorageSync(storageKey) || 0;
        }

        // 递增计数
        const newCount = currentCount + 1;

        // 保存计数和日期
        wx.setStorageSync(storageKey, newCount);
        wx.setStorageSync(dateKey, today);

        return newCount;
    } catch (error) {
        console.error('获取事件计数失败:', error);
        return 1; // 如果存储失败，返回 1
    }
}

/**
 * 埋点追踪器（单例模式）
 */
class Tracker {
    private static instance: Tracker | null = null;
    private openLog: boolean;

    private constructor() {
        this.openLog = true;
    }

    /**
     * 获取 Tracker 单例实例
     */
    public static getInstance(): Tracker {
        if (!Tracker.instance) {
            Tracker.instance = new Tracker();
        }
        return Tracker.instance;
    }

    printLog(tip: string, message?: string | object): void {
        if (this.openLog) {
            if (message) {
                if (typeof message === 'object') {
                    console.log(tip, ':', JSON.stringify(message, null, 2));
                } else {
                    console.log(tip, ':', message as string);
                }
            } else {
                console.log(tip);
            }
        }
    }

    /**
     * 生成公共埋点属性
     * @param eventName 事件名称
     * @param pageName 页面名称
     * @param extraParams 额外的参数对象
     * @returns 包含公共属性和额外参数的埋点参数对象
     */
    private getCommonEventParams(
        eventName: string,
        pageName: string,
        extraParams?: Record<string, any>,
    ): Record<string, any> {
        return {
            count: getEventCount(eventName),
            date_time: formatTime(),
            uuid: getAppUUID(),
            page_name: pageName,
            ...extraParams,
        };
    }

    /**
     * 上报分享点击事件
     * @param pageName 页面名称
     */
    reportShare(pageName: string): void {
        try {
            const params = this.getCommonEventParams('share_click', pageName);

            this.sendEvent('share_click', params);
        } catch (error) {
            console.error('上报分享事件失败:', error);
        }
    }

    /**
     * 上报下载打印事件
     * @param pageName 页面名称
     * @param mode 模式（可选）
     */
    reportDownload(pageName: string, mode?: string): void {
        try {
            const params = this.getCommonEventParams('download', pageName, {
                ...(mode && { mode }),
            });

            this.sendEvent('download', params);
        } catch (error) {
            console.error('上报下载事件失败:', error);
        }
    }

    /**
     * 发送事件（仅在线上环境上报）
     * @param eventName 事件名称
     * @param params 事件参数
     */
    sendEvent(eventName: string, params: Record<string, any>): void {
        try {
            // 获取当前环境，只在 release 环境下上报
            const accountInfo = wx.getAccountInfoSync();
            const env = accountInfo.miniProgram.envVersion || 'release';

            if (env === 'release') {
                this.printLog(`[${env}] 事件上报`, { eventName, params });
                wx.reportEvent(eventName, params);
            } else {
                // 非线上环境，只打印日志，不上报
                this.printLog(`[${env}] 事件上报已跳过`, { eventName, params });
            }
        } catch (error) {
            console.error('获取环境信息失败:', error);
            // 如果获取环境信息失败，为了安全起见不上报
        }
    }
}

// 导出 Tracker 单例实例
const tracker = Tracker.getInstance();

export default tracker;
