function _class_call_check(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}
function _defineProperties(target, props) {
    for(var i = 0; i < props.length; i++){
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}
function _create_class(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    return Constructor;
}
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
var DEFAULT_CHARS_PER_FRAME = 3;
var DEFAULT_SPEED = 1.0;
var DEFAULT_BACKGROUND_INTERVAL = 100;
var DEFAULT_BACKGROUND_BATCH_MULTIPLIER = 10;
/**
 * 字符队列——流式渲染的调度核心。
 *
 * - 接收 SSE 推送的 content（完整字符串，非增量）
 * - 标签页可见时以 RAF 驱动逐字输出（60fps 动画）
 * - 标签页不可见时降级为 setTimeout，保证后台仍能消费
 * - 切回前台时自动恢复 RAF
 */ export var CharacterQueue = /*#__PURE__*/ function() {
    "use strict";
    function CharacterQueue(onFlush, options) {
        var _this = this;
        _class_call_check(this, CharacterQueue);
        var _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
        _define_property(this, "displayedLength", 0);
        _define_property(this, "fullContent", '');
        _define_property(this, "rafId", null);
        _define_property(this, "timerId", null);
        _define_property(this, "tickMode", 'raf');
        _define_property(this, "onFlush", void 0);
        _define_property(this, "options", void 0);
        _define_property(this, "disposed", false);
        _define_property(this, "tick", function() {
            _this.rafId = null;
            _this.timerId = null;
            if (_this.disposed) return;
            var remaining = _this.fullContent.length - _this.displayedLength;
            if (remaining <= 0) return;
            var isVisible = typeof document !== 'undefined' && document.visibilityState === 'visible';
            var baseBatch = Math.max(1, Math.ceil(_this.options.charsPerFrame * _this.options.speed));
            var batchSize = isVisible ? baseBatch : baseBatch * _this.options.backgroundBatchMultiplier;
            _this.displayedLength = Math.min(_this.displayedLength + batchSize, _this.fullContent.length);
            _this.onFlush(_this.fullContent.slice(0, _this.displayedLength));
            if (_this.displayedLength < _this.fullContent.length) {
                _this.scheduleNext(isVisible);
            }
        });
        this.onFlush = onFlush;
        this.options = {
            charsPerFrame: (_ref = options === null || options === void 0 ? void 0 : options.charsPerFrame) !== null && _ref !== void 0 ? _ref : DEFAULT_CHARS_PER_FRAME,
            animate: (_ref1 = options === null || options === void 0 ? void 0 : options.animate) !== null && _ref1 !== void 0 ? _ref1 : true,
            speed: (_ref2 = options === null || options === void 0 ? void 0 : options.speed) !== null && _ref2 !== void 0 ? _ref2 : DEFAULT_SPEED,
            flushOnComplete: (_ref3 = options === null || options === void 0 ? void 0 : options.flushOnComplete) !== null && _ref3 !== void 0 ? _ref3 : true,
            backgroundInterval: (_ref4 = options === null || options === void 0 ? void 0 : options.backgroundInterval) !== null && _ref4 !== void 0 ? _ref4 : DEFAULT_BACKGROUND_INTERVAL,
            backgroundBatchMultiplier: (_ref5 = options === null || options === void 0 ? void 0 : options.backgroundBatchMultiplier) !== null && _ref5 !== void 0 ? _ref5 : DEFAULT_BACKGROUND_BATCH_MULTIPLIER,
            animateTailChars: options === null || options === void 0 ? void 0 : options.animateTailChars
        };
        this.handleVisibilityChange = this.handleVisibilityChange.bind(this);
        if (typeof document !== 'undefined') {
            document.addEventListener('visibilitychange', this.handleVisibilityChange);
        }
    }
    _create_class(CharacterQueue, [
        {
            /** SSE token 到达时调用——接收完整的 content 字符串 */ key: "push",
            value: function push(content) {
                if (content.length < this.displayedLength) {
                    this.displayedLength = 0;
                }
                this.fullContent = content;
                if (!this.options.animate) {
                    this.displayedLength = content.length;
                    this.onFlush(content);
                    return;
                }
                // 仅对末尾 N 字做动画：立即展示前面内容
                var tail = this.options.animateTailChars;
                if (tail !== undefined && tail > 0 && content.length > tail) {
                    var staticLength = content.length - tail;
                    this.displayedLength = Math.max(this.displayedLength, staticLength);
                    this.onFlush(content.slice(0, this.displayedLength));
                }
                this.ensureTicking();
            }
        },
        {
            /** 标记流式完成，flush 所有剩余内容 */ key: "complete",
            value: function complete() {
                if (this.options.flushOnComplete) {
                    this.cancelAllTicks();
                    this.displayedLength = this.fullContent.length;
                    this.onFlush(this.fullContent);
                }
            }
        },
        {
            /** 释放资源 */ key: "dispose",
            value: function dispose() {
                this.disposed = true;
                this.cancelAllTicks();
                if (typeof document !== 'undefined') {
                    document.removeEventListener('visibilitychange', this.handleVisibilityChange);
                }
            }
        },
        {
            key: "getDisplayedLength",
            value: function getDisplayedLength() {
                return this.displayedLength;
            }
        },
        {
            key: "getFullContent",
            value: function getFullContent() {
                return this.fullContent;
            }
        },
        {
            key: "ensureTicking",
            value: // ---- 调度核心 ----
            function ensureTicking() {
                if (this.disposed || this.isTickActive()) return;
                var isVisible = typeof document !== 'undefined' && document.visibilityState === 'visible';
                this.tickMode = isVisible ? 'raf' : 'timeout';
                if (this.tickMode === 'raf') {
                    this.rafId = requestAnimationFrame(this.tick);
                } else {
                    this.timerId = setTimeout(this.tick, this.options.backgroundInterval);
                }
            }
        },
        {
            key: "scheduleNext",
            value: function scheduleNext(isVisible) {
                if (isVisible) {
                    this.tickMode = 'raf';
                    this.rafId = requestAnimationFrame(this.tick);
                } else {
                    this.tickMode = 'timeout';
                    this.timerId = setTimeout(this.tick, this.options.backgroundInterval);
                }
            }
        },
        {
            key: "handleVisibilityChange",
            value: function handleVisibilityChange() {
                if (this.disposed) return;
                if (this.displayedLength >= this.fullContent.length) return;
                this.cancelAllTicks();
                this.ensureTicking();
            }
        },
        {
            key: "isTickActive",
            value: function isTickActive() {
                return this.rafId !== null || this.timerId !== null;
            }
        },
        {
            key: "cancelAllTicks",
            value: function cancelAllTicks() {
                if (this.rafId !== null) {
                    cancelAnimationFrame(this.rafId);
                    this.rafId = null;
                }
                if (this.timerId !== null) {
                    clearTimeout(this.timerId);
                    this.timerId = null;
                }
            }
        }
    ]);
    return CharacterQueue;
}();
