/**
 * listFrameThrottler - 帧级节流器 -- 只用于持仓订单
 * 收集同一帧内的所有数据，帧结束时只推送最后一个值
 */

export type FrameThrottlerData = object;

export type FrameThrottlerCallback = (data: FrameThrottlerData[]) => void;

export class ListFrameThrottler {
    private callback: FrameThrottlerCallback;
    private pendingData: Map<string, FrameThrottlerData>;
    private rafId: number | null;
    private fallbackTimer: ReturnType<typeof setInterval> | null;
    private isVisible: boolean;

    constructor(callback: FrameThrottlerCallback) {
        this.callback = callback;
        this.pendingData = new Map();
        this.rafId = null;
        this.fallbackTimer = null;
        this.isVisible = true;
        this._bindVisibility();
    }

    // 监听页面可见性变化
    _bindVisibility() {
        if (typeof document === 'undefined') return;

        document.addEventListener('visibilitychange', () => {
            this.isVisible = !document.hidden;
            if (this.isVisible) {
                // 切回前台：立即刷新积压数据
                this._clearFallback();
                this.flush();
            } else {
                // 切入后台：启动定时器兜底
                this._startFallback();
            }
        });
    }

    // 后台兜底：用 setTimeout 替代 rAF
    private _startFallback() {
        this._clearFallback();
        this.fallbackTimer = setInterval(() => {
            if (this.pendingData.size > 0) {
                this._flush();
            }
        }, 500);
    }

    private _clearFallback() {
        if (this.fallbackTimer) {
            clearInterval(this.fallbackTimer);
            this.fallbackTimer = null;
        }
    }

    /**
     * 推送数据（同一帧内多次调用只保留最后一个）
     */
    push(data: FrameThrottlerData) {
        const dataRecord = data as Record<string, unknown>;
        const key = String((dataRecord.id as string | number | undefined) ?? JSON.stringify(data));
        this.pendingData.set(key, data);

        if (!this.rafId) {
            this.rafId = requestAnimationFrame(() => this._flush());
        }
    }

    /**
     * 帧结束时的回调：只推送最后一个数据
     */
    _flush() {
        this.rafId = null;
        const list = [...this.pendingData.values()]
        if (list.length === 0) return;
        this.pendingData = new Map(); // 清空缓存
        this.callback(list);
    }

    /**
     * 立即刷新（手动触发）
     */
    flush() {
        if (this.rafId) {
            cancelAnimationFrame(this.rafId);
            this.rafId = null;
        }
        this._clearFallback();
        this._flush();
    }

    /**
     * 销毁实例
     */
    destroy() {
        if (this.rafId) {
            cancelAnimationFrame(this.rafId);
            this.rafId = null;
        }
        this._clearFallback();
        this.pendingData = new Map();
        this.callback = () => {};
    }
}
