export function mergePatchedItems(toMerge, { page, itemKey, orders, itemPredicate, }) {
    const itemsToMerge = toMerge.all;
    // merge items into page. replace if already exists in page. order by original if `keepPosition=true`
    const pageWithPatchedItemsMapTmp = new Map();
    for (const [key, { item, optimisticPatch }] of Array.from(itemsToMerge.entries())) {
        const { keepPosition, originalItems } = optimisticPatch;
        const originalItem = originalItems.get(key);
        // if `order` is empty (can't simulate ordering) and keepPosition=true and item didn't match current filtering before update
        // skip on pushing the item into the page
        if (!orders.length &&
            keepPosition &&
            originalItem != null &&
            itemPredicate(originalItem)) {
            continue;
        }
        if (!itemPredicate(item)) {
            continue;
        }
        pageWithPatchedItemsMapTmp.set(key, { item });
    }
    // place "type=createMany" items first
    const pageWithPatchedItemsMap = new Map();
    for (const key of toMerge.created.keys()) {
        if (pageWithPatchedItemsMapTmp.has(key)) {
            pageWithPatchedItemsMap.set(key, {
                item: pageWithPatchedItemsMapTmp.get(key).item,
            });
            pageWithPatchedItemsMapTmp.delete(key);
        }
    }
    for (const [key, { item }] of Array.from(pageWithPatchedItemsMapTmp.entries())) {
        pageWithPatchedItemsMap.set(key, { item });
    }
    for (const item of page) {
        const key = itemKey(item);
        const toInsert = itemsToMerge.get(key);
        if (toInsert && toInsert.optimisticPatch.keepPosition) {
            pageWithPatchedItemsMap.delete(key);
            pageWithPatchedItemsMap.set(key, {
                item: toInsert.item,
                orderByItem: item,
            });
        }
        else if (!toInsert) {
            pageWithPatchedItemsMap.set(key, { item });
        }
    }
    const result = Array.from(pageWithPatchedItemsMap.values());
    // Reposition created items that specify afterItemKey
    for (const [key, { optimisticPatch }] of toMerge.created.entries()) {
        if (optimisticPatch.afterItemKey == null) {
            continue;
        }
        const currentIdx = result.findIndex((e) => itemKey(e.item) === key);
        if (currentIdx === -1) {
            continue;
        }
        const anchorIdx = result.findIndex((e) => itemKey(e.item) === optimisticPatch.afterItemKey);
        if (anchorIdx !== -1) {
            // Anchor found on this page — reposition after it
            const [entry] = result.splice(currentIdx, 1);
            const newAnchorIdx = result.findIndex((e) => itemKey(e.item) === optimisticPatch.afterItemKey);
            result.splice(newAnchorIdx + 1, 0, entry);
            // Remove from shared maps: 'all' so trimAddedItemsFromPagePredicate
            // won't exclude it at the page boundary; 'created' so later pages
            // won't attempt to reposition it again.
            toMerge.all.delete(key);
            toMerge.created.delete(key);
        }
        else {
            // Anchor not on this page — remove from this page's result but keep
            // in toMerge so the item surfaces on whichever page contains the anchor.
            result.splice(currentIdx, 1);
        }
    }
    return result;
}
//# sourceMappingURL=mergePatchedItems.js.map