"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.promise = void 0;
const types_1 = require("../../config/types");
const traverseFields_1 = require("./traverseFields");
// This function is responsible for the following actions, in order:
// - Execute field hooks
const promise = async ({ data, doc, field, operation, req, siblingData, siblingDoc, }) => {
    var _a;
    if ((0, types_1.fieldAffectsData)(field)) {
        // Execute hooks
        if ((_a = field.hooks) === null || _a === void 0 ? void 0 : _a.afterChange) {
            await field.hooks.afterChange.reduce(async (priorHook, currentHook) => {
                await priorHook;
                const hookedValue = await currentHook({
                    value: siblingData[field.name],
                    originalDoc: doc,
                    data,
                    siblingData,
                    operation,
                    req,
                });
                if (hookedValue !== undefined) {
                    siblingDoc[field.name] = hookedValue;
                }
            }, Promise.resolve());
        }
    }
    // Traverse subfields
    switch (field.type) {
        case 'group': {
            await (0, traverseFields_1.traverseFields)({
                data,
                doc,
                fields: field.fields,
                operation,
                req,
                siblingData: siblingData[field.name] || {},
                siblingDoc: siblingDoc[field.name],
            });
            break;
        }
        case 'array': {
            const rows = siblingDoc[field.name];
            if (Array.isArray(rows)) {
                const promises = [];
                rows.forEach((row, i) => {
                    var _a;
                    promises.push((0, traverseFields_1.traverseFields)({
                        data,
                        doc,
                        fields: field.fields,
                        operation,
                        req,
                        siblingData: ((_a = siblingData[field.name]) === null || _a === void 0 ? void 0 : _a[i]) || {},
                        siblingDoc: { ...row } || {},
                    }));
                });
                await Promise.all(promises);
            }
            break;
        }
        case 'blocks': {
            const rows = siblingDoc[field.name];
            if (Array.isArray(rows)) {
                const promises = [];
                rows.forEach((row, i) => {
                    var _a;
                    const block = field.blocks.find((blockType) => blockType.slug === row.blockType);
                    if (block) {
                        promises.push((0, traverseFields_1.traverseFields)({
                            data,
                            doc,
                            fields: block.fields,
                            operation,
                            req,
                            siblingData: ((_a = siblingData[field.name]) === null || _a === void 0 ? void 0 : _a[i]) || {},
                            siblingDoc: { ...row } || {},
                        }));
                    }
                });
                await Promise.all(promises);
            }
            break;
        }
        case 'row':
        case 'collapsible': {
            await (0, traverseFields_1.traverseFields)({
                data,
                doc,
                fields: field.fields,
                operation,
                req,
                siblingData: siblingData || {},
                siblingDoc: { ...siblingDoc },
            });
            break;
        }
        case 'tabs': {
            const promises = [];
            field.tabs.forEach((tab) => {
                promises.push((0, traverseFields_1.traverseFields)({
                    data,
                    doc,
                    fields: tab.fields,
                    operation,
                    req,
                    siblingData: siblingData || {},
                    siblingDoc: { ...siblingDoc },
                }));
            });
            await Promise.all(promises);
            break;
        }
        default: {
            break;
        }
    }
};
exports.promise = promise;
//# sourceMappingURL=data:application/json;base64, 