import { fieldHasSubFields } from '../fields/config/types.js';
const traverseArrayOrBlocksField = ({ callback, data, field, fillEmpty, parentRef })=>{
    if (fillEmpty) {
        if (field.type === 'array') {
            traverseFields({
                callback,
                fields: field.fields,
                parentRef
            });
        }
        if (field.type === 'blocks') {
            field.blocks.forEach((block)=>{
                traverseFields({
                    callback,
                    fields: block.fields,
                    parentRef
                });
            });
        }
        return;
    }
    for (const ref of data){
        let fields;
        let flattenedFields;
        if (field.type === 'blocks' && typeof ref?.blockType === 'string') {
            const block = field.blocks.find((block)=>block.slug === ref.blockType);
            fields = block?.fields;
            flattenedFields = block?.flattenedFields;
        } else if (field.type === 'array') {
            fields = field.fields;
            flattenedFields = field?.flattenedFields;
        }
        if (flattenedFields || fields) {
            traverseFields({
                callback,
                fields,
                fillEmpty,
                flattenedFields,
                parentRef,
                ref
            });
        }
    }
};
/**
 * Iterate a recurse an array of fields, calling a callback for each field
 *
 * @param fields
 * @param callback callback called for each field, discontinue looping if callback returns truthy
 * @param fillEmpty fill empty properties to use this without data
 * @param ref the data or any artifacts assigned in the callback during field recursion
 * @param parentRef the data or any artifacts assigned in the callback during field recursion one level up
 */ export const traverseFields = ({ callback, fields, fillEmpty = true, flattenedFields, parentRef = {}, ref = {} })=>{
    ;
    (flattenedFields ?? fields).some((field)=>{
        let skip = false;
        const next = ()=>{
            skip = true;
        };
        if (!ref || typeof ref !== 'object') {
            return;
        }
        if (callback && callback({
            // @ts-expect-error compatibillity Field | FlattenedField
            field,
            next,
            parentRef,
            ref
        })) {
            return true;
        }
        if (skip) {
            return false;
        }
        // avoid mutation of ref for all fields
        let currentRef = ref;
        let currentParentRef = parentRef;
        if (field.type === 'tabs' && 'tabs' in field) {
            for (const tab of field.tabs){
                let tabRef = ref;
                if ('name' in tab && tab.name) {
                    if (!ref[tab.name] || typeof ref[tab.name] !== 'object') {
                        if (fillEmpty) {
                            ref[tab.name] = {};
                        } else {
                            continue;
                        }
                    }
                    tabRef = tabRef[tab.name];
                    if (tab.localized) {
                        for(const key in tabRef){
                            if (tabRef[key] && typeof tabRef[key] === 'object') {
                                traverseFields({
                                    callback,
                                    fields: tab.fields,
                                    fillEmpty,
                                    parentRef: currentParentRef,
                                    ref: tabRef[key]
                                });
                            }
                        }
                        continue;
                    }
                }
                if (callback && callback({
                    // @ts-expect-error compatibillity Field | FlattenedField
                    field: {
                        ...tab,
                        type: 'tab'
                    },
                    next,
                    parentRef: currentParentRef,
                    ref: tabRef
                })) {
                    return true;
                }
                traverseFields({
                    callback,
                    fields: tab.fields,
                    fillEmpty,
                    parentRef: currentParentRef,
                    ref: tabRef
                });
            }
            return;
        }
        if ((flattenedFields || field.type !== 'tab') && (fieldHasSubFields(field) || field.type === 'tab' || field.type === 'blocks')) {
            if ('name' in field && field.name) {
                currentParentRef = currentRef;
                if (!ref[field.name]) {
                    if (fillEmpty) {
                        if (field.type === 'group' || field.type === 'tab') {
                            ref[field.name] = {};
                        } else if (field.type === 'array' || field.type === 'blocks') {
                            if (field.localized) {
                                ref[field.name] = {};
                            } else {
                                ref[field.name] = [];
                            }
                        }
                    } else {
                        return;
                    }
                }
                currentRef = ref[field.name];
            }
            if ((field.type === 'group' || field.type === 'tab') && field.localized && currentRef && typeof currentRef === 'object') {
                for(const key in currentRef){
                    if (currentRef[key]) {
                        traverseFields({
                            callback,
                            fields: field.fields,
                            fillEmpty,
                            flattenedFields: 'flattenedFields' in field ? field.flattenedFields : undefined,
                            parentRef: currentParentRef,
                            ref: currentRef[key]
                        });
                    }
                }
                return;
            }
            if ((field.type === 'blocks' || field.type === 'array') && currentRef && typeof currentRef === 'object') {
                if (field.localized) {
                    if (Array.isArray(currentRef)) {
                        return;
                    }
                    for(const key in currentRef){
                        const localeData = currentRef[key];
                        if (!Array.isArray(localeData)) {
                            continue;
                        }
                        traverseArrayOrBlocksField({
                            callback,
                            data: localeData,
                            field,
                            fillEmpty,
                            parentRef: currentParentRef
                        });
                    }
                } else if (Array.isArray(currentRef)) {
                    traverseArrayOrBlocksField({
                        callback,
                        data: currentRef,
                        field,
                        fillEmpty,
                        parentRef: currentParentRef
                    });
                }
            } else if (currentRef && typeof currentRef === 'object' && 'fields' in field) {
                traverseFields({
                    callback,
                    fields: field.fields,
                    fillEmpty,
                    flattenedFields: 'flattenedFields' in field ? field.flattenedFields : undefined,
                    parentRef: currentParentRef,
                    ref: currentRef
                });
            }
        }
    });
};

//# sourceMappingURL=traverseFields.js.map