/**
 * Bubble 自定义 memo 比较（见 Bubble.tsx）。
 *
 * 维护约定：
 * - 在 BubbleProps 上新增「会影响渲染」的字段时，必须在此补充比较逻辑，否则可能漏更新。
 * - `markdownRenderConfig` / `bubbleRenderConfig` / `docListProps` / `customConfig`：按**顶层键**浅比较；
 *   顶层值为普通对象时再浅比较一层；数组与函数仍按引用比较。父组件用 `useMemo` 稳定子对象引用更佳。
 * - `originData`：按列出的标量与引用字段比较；`meta` 顶层浅比较；`meta.metadata` 再浅比较一层。
 *   对 `extra` 等对象请勿原地 mutate，应替换引用，否则可能与 `extra !==` 不一致（若仅改嵌套且未换引用会漏更新）。
 */ function _array_like_to_array(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
    return arr2;
}
function _array_without_holes(arr) {
    if (Array.isArray(arr)) return _array_like_to_array(arr);
}
function _iterable_to_array(iter) {
    if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _non_iterable_spread() {
    throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _to_consumable_array(arr) {
    return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
}
function _type_of(obj) {
    "@swc/helpers - typeof";
    return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
}
function _unsupported_iterable_to_array(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _array_like_to_array(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(n);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
export var shallowEqualRecord = function shallowEqualRecord(a, b) {
    if (a === b) return true;
    if (!a || !b) return !a && !b;
    var keysA = Object.keys(a);
    var keysB = Object.keys(b);
    if (keysA.length !== keysB.length) return false;
    var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
    try {
        for(var _iterator = keysA[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
            var k = _step.value;
            if (a[k] !== b[k]) {
                return false;
            }
        }
    } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
    } finally{
        try {
            if (!_iteratorNormalCompletion && _iterator.return != null) {
                _iterator.return();
            }
        } finally{
            if (_didIteratorError) {
                throw _iteratorError;
            }
        }
    }
    return true;
};
export var shallowEqualStyles = function shallowEqualStyles(a, b) {
    if (a === b) return true;
    if (!a || !b) return !a && !b;
    var keys = new Set(_to_consumable_array(Object.keys(a)).concat(_to_consumable_array(Object.keys(b))));
    var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
    try {
        for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
            var k = _step.value;
            var va = a[k];
            var vb = b[k];
            if (va === vb) continue;
            if (va && vb && (typeof va === "undefined" ? "undefined" : _type_of(va)) === 'object' && (typeof vb === "undefined" ? "undefined" : _type_of(vb)) === 'object' && !Array.isArray(va) && !Array.isArray(vb)) {
                if (!shallowEqualRecord(va, vb)) {
                    return false;
                }
            } else {
                return false;
            }
        }
    } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
    } finally{
        try {
            if (!_iteratorNormalCompletion && _iterator.return != null) {
                _iterator.return();
            }
        } finally{
            if (_didIteratorError) {
                throw _iteratorError;
            }
        }
    }
    return true;
};
var shallowEqualClassNames = function shallowEqualClassNames(a, b) {
    if (a === b) return true;
    if (!a || !b) return !a && !b;
    var keys = new Set(_to_consumable_array(Object.keys(a)).concat(_to_consumable_array(Object.keys(b))));
    var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
    try {
        for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
            var k = _step.value;
            if (a[k] !== b[k]) {
                return false;
            }
        }
    } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
    } finally{
        try {
            if (!_iteratorNormalCompletion && _iterator.return != null) {
                _iterator.return();
            }
        } finally{
            if (_didIteratorError) {
                throw _iteratorError;
            }
        }
    }
    return true;
};
/** 配置型 props：顶层浅比较；顶层值为非数组对象时再浅比较一层 */ var shallowEqualConfigObject = function shallowEqualConfigObject(a, b) {
    if (a === b) return true;
    if (!a || !b) return !a && !b;
    var ra = a;
    var rb = b;
    var keys = new Set(_to_consumable_array(Object.keys(ra)).concat(_to_consumable_array(Object.keys(rb))));
    var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
    try {
        for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
            var k = _step.value;
            if (!(k in ra) || !(k in rb)) return false;
            var va = ra[k];
            var vb = rb[k];
            if (va === vb) continue;
            if (va && vb && (typeof va === "undefined" ? "undefined" : _type_of(va)) === 'object' && (typeof vb === "undefined" ? "undefined" : _type_of(vb)) === 'object' && !Array.isArray(va) && !Array.isArray(vb)) {
                if (!shallowEqualRecord(va, vb)) {
                    return false;
                }
            } else {
                return false;
            }
        }
    } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
    } finally{
        try {
            if (!_iteratorNormalCompletion && _iterator.return != null) {
                _iterator.return();
            }
        } finally{
            if (_didIteratorError) {
                throw _iteratorError;
            }
        }
    }
    return true;
};
var metaAffectsBubble = function metaAffectsBubble(m) {
    return Boolean((m === null || m === void 0 ? void 0 : m.avatar) || (m === null || m === void 0 ? void 0 : m.title) || (m === null || m === void 0 ? void 0 : m.name) || (m === null || m === void 0 ? void 0 : m.description) || (m === null || m === void 0 ? void 0 : m.backgroundColor) || (m === null || m === void 0 ? void 0 : m.metadata) && Object.keys(m.metadata).length > 0);
};
var metaEqualForMemo = function metaEqualForMemo(a, b) {
    if (a === b) return true;
    if (!shallowEqualRecord(a || {}, b || {})) {
        return false;
    }
    var ma = a === null || a === void 0 ? void 0 : a.metadata;
    var mb = b === null || b === void 0 ? void 0 : b.metadata;
    if (ma === mb) return true;
    if (!ma || !mb) return !ma && !mb;
    return shallowEqualRecord(ma, mb);
};
var originDataEqualForMemo = function originDataEqualForMemo(a, b) {
    if (a === b) return true;
    if (!a || !b) return false;
    if (a.id !== b.id || a.role !== b.role || a.content !== b.content || a.isFinished !== b.isFinished || a.isAborted !== b.isAborted || a.isLast !== b.isLast || a.isLatest !== b.isLatest || a.updateAt !== b.updateAt || a.createAt !== b.createAt || a.feedback !== b.feedback || a.originContent !== b.originContent || a.fileMap !== b.fileMap || a.extra !== b.extra || a.error !== b.error) {
        return false;
    }
    if (a.meta === b.meta) return true;
    if (!metaAffectsBubble(a.meta) && !metaAffectsBubble(b.meta)) return true;
    return metaEqualForMemo(a.meta, b.meta);
};
var preMessageEqualForMemo = function preMessageEqualForMemo(a, b) {
    if (a === b) return true;
    if (!a || !b) return false;
    return a.id === b.id && a.role === b.role;
};
var depsArrayEqual = function depsArrayEqual(a, b) {
    if (a === b) return true;
    if (!a || !b) return !a && !b;
    if (a.length !== b.length) return false;
    for(var i = 0; i < a.length; i++){
        if (a[i] !== b[i]) return false;
    }
    return true;
};
/**
 * Custom props comparator for Bubble memo.
 * BubbleList (and callers) often pass fresh object references for styles / classNames / avatar
 * while message data is unchanged; default shallow compare would still re-render every parent tick.
 */ export var bubblePropsAreEqual = function bubblePropsAreEqual(prev, next) {
    if (prev === next) return true;
    if (prev.id !== next.id) return false;
    if (prev.placement !== next.placement) return false;
    if (prev.pure !== next.pure) return false;
    if (prev.readonly !== next.readonly) return false;
    if (prev.time !== next.time) return false;
    if (prev.shouldShowVoice !== next.shouldShowVoice) return false;
    if (prev.renderMode !== next.renderMode) return false;
    if (prev.renderType !== next.renderType) return false;
    if (prev.shouldShowCopy !== next.shouldShowCopy) return false;
    if (typeof prev.shouldShowCopy === 'function' || typeof next.shouldShowCopy === 'function') {
        if (prev.shouldShowCopy !== next.shouldShowCopy) return false;
    }
    if (!originDataEqualForMemo(prev.originData, next.originData)) return false;
    if (!preMessageEqualForMemo(prev.preMessage, next.preMessage)) return false;
    if (!shallowEqualConfigObject(prev.markdownRenderConfig, next.markdownRenderConfig)) {
        return false;
    }
    if (!shallowEqualConfigObject(prev.bubbleRenderConfig, next.bubbleRenderConfig)) {
        return false;
    }
    if (!shallowEqualConfigObject(prev.docListProps, next.docListProps)) {
        return false;
    }
    if (!shallowEqualConfigObject(prev.customConfig, next.customConfig)) {
        return false;
    }
    if (prev.bubbleListRef !== next.bubbleListRef) return false;
    if (prev.bubbleRef !== next.bubbleRef) return false;
    if (prev.avatar === next.avatar) {
    // ok
    } else if (!shallowEqualRecord(prev.avatar, next.avatar)) {
        return false;
    }
    if (!shallowEqualStyles(prev.styles, next.styles)) return false;
    if (!shallowEqualClassNames(prev.classNames, next.classNames)) return false;
    if (prev.style !== next.style) {
        if (!shallowEqualRecord(prev.style || {}, next.style || {})) {
            return false;
        }
    }
    if (prev.className !== next.className) return false;
    if (prev.onReply !== next.onReply) return false;
    if (prev.onDisLike !== next.onDisLike) return false;
    if (prev.onDislike !== next.onDislike) return false;
    if (prev.onLike !== next.onLike) return false;
    if (prev.onCancelLike !== next.onCancelLike) return false;
    if (prev.onLikeCancel !== next.onLikeCancel) return false;
    if (prev.onAvatarClick !== next.onAvatarClick) return false;
    if (prev.onDoubleClick !== next.onDoubleClick) return false;
    if (prev.useSpeech !== next.useSpeech) return false;
    if (prev.fileViewEvents !== next.fileViewEvents) return false;
    if (prev.fileViewConfig !== next.fileViewConfig) return false;
    if (prev.renderFileMoreAction !== next.renderFileMoreAction) return false;
    if (prev.userBubbleProps !== next.userBubbleProps) return false;
    if (prev.aiBubbleProps !== next.aiBubbleProps) return false;
    if (prev.aIBubbleProps !== next.aIBubbleProps) return false;
    if (!depsArrayEqual(prev.deps, next.deps)) return false;
    return true;
};
