const callbackCaller = (cb) => cb();
export const createOperationResultHandler = (articleRegistry, articleQuery, notificationCenter, hooks) => {
    const batchUpdates = articleRegistry.executeBatch === undefined
        ? callbackCaller
        : articleRegistry.executeBatch;
    const processOperationResults = async (results) => {
        if (results.length === 0) {
            return;
        }
        await hooks.beforeOperationResultProcessing.emit(results);
        const processResults = [];
        batchUpdates(() => {
            for (const result of results) {
                const processor = resultProcessor[result.type];
                const processedResult = processor(result, articleRegistry, articleQuery, hooks);
                processResults.push(processedResult);
            }
        });
        await hooks.afterOperationResultProcessing.emit(results);
        for (const entry of processResults) {
            if (entry === undefined) {
                continue;
            }
            if (Array.isArray(entry)) {
                for (const notification of entry) {
                    notificationCenter.send("OperationResultHandler", notification.name, notification.payload);
                }
            }
            else {
                notificationCenter.send("OperationResultHandler", entry.name, entry.payload);
            }
        }
    };
    return {
        processOperationResults,
    };
};
const processCreateResult = ({ articleType, data, type, ...result }, articleRegistry, articleQuery, hooks) => {
    const registerData = {
        ...result,
        data: data || {},
        type: articleType,
    };
    hooks.beforeArticleRegistration.emit(registerData);
    articleRegistry.registerArticle(registerData);
    const article = articleQuery.getArticleByComId(result.comId);
    hooks.afterArticleRegistration.emit(article);
    return {
        name: "ItemCreated",
        payload: article,
    };
};
const processChangeResult = ({ type, comId, ...updateData }, articleRegistry, articleQuery, hooks) => {
    const oldArticle = articleQuery.getArticleByComId(comId);
    hooks.beforeArticleUpdate.emit(oldArticle, updateData);
    articleRegistry.updateArticle(comId, updateData);
    const newArticle = articleQuery.getArticleByComId(comId);
    hooks.beforeArticleUpdate.emit(newArticle, updateData);
    return [
        {
            name: "ItemConfigured",
            payload: newArticle,
        },
        {
            name: "ItemChanged",
            payload: {
                previousArticle: oldArticle,
                article: newArticle,
            },
        },
    ];
};
const processDeleteResult = (result, articleRegistry, articleQuery, hooks) => {
    const currentArticle = articleQuery.getArticleByComId(result.comId);
    hooks.beforeArticleUnregistration.emit(currentArticle);
    articleRegistry.unregisterArticle(result.comId);
    hooks.beforeArticleRegistration.emit(currentArticle);
    return {
        name: "ItemRemoved",
        payload: currentArticle,
    };
};
const resultProcessor = {
    create: processCreateResult,
    change: processChangeResult,
    delete: processDeleteResult,
};
