"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.clearSectionFormContent = exports.collectSectionClearTargets = exports.sectionHasContentData = exports.getValueByPath = exports.findAllNames = exports.getSpliceTarget = exports.findNameWithIndexName = exports.getArrayPathForNameWithIndexName = void 0;
const lodash_1 = require("lodash");
const getStaticPrefixBeforeArrayProp = (templateName) => {
    const firstBracketIndex = templateName.indexOf('[');
    if (firstBracketIndex < 0) {
        return '';
    }
    const beforeFirstBracket = templateName.slice(0, firstBracketIndex);
    const lastDotIndex = beforeFirstBracket.lastIndexOf('.');
    if (lastDotIndex < 0) {
        return '';
    }
    return beforeFirstBracket.slice(0, lastDotIndex);
};
const getSegmentsFromTemplate = (templateName) => {
    const re = /(\w+)\[(?:\{\{(\w+)\}\}|(\d+))\]/g;
    const segments = [];
    let match;
    while ((match = re.exec(templateName)) !== null) {
        const prop = match[1] ?? '';
        const placeholder = match[2];
        const fixedIndex = match[3];
        if (placeholder !== undefined) {
            segments.push({ type: 'placeholder', prop, placeholder });
        }
        else if (fixedIndex !== undefined) {
            const index = parseInt(fixedIndex, 10);
            if (!Number.isNaN(index)) {
                segments.push({ type: 'fixed', prop, index });
            }
        }
    }
    return segments;
};
const getArrayPathForNameWithIndexName = (templateName, placeholder) => {
    const staticPrefix = getStaticPrefixBeforeArrayProp(templateName);
    const segments = getSegmentsFromTemplate(templateName);
    const placeholderIdx = segments.findIndex((s) => s.type === 'placeholder' && s.placeholder === placeholder);
    if (placeholderIdx < 0) {
        return undefined;
    }
    for (let i = 0; i < placeholderIdx; i++) {
        const seg = segments[i];
        if (!seg || seg.type !== 'fixed') {
            return undefined;
        }
    }
    const prefixParts = [];
    for (let i = 0; i < placeholderIdx; i++) {
        const s = segments[i];
        prefixParts.push(`${s.prop}[${s.index}]`);
    }
    const at = segments[placeholderIdx];
    const dynamicPrefix = prefixParts.join('.');
    const combinedPrefix = [staticPrefix, dynamicPrefix].filter(Boolean).join('.');
    return combinedPrefix ? `${combinedPrefix}.${at.prop}` : at.prop;
};
exports.getArrayPathForNameWithIndexName = getArrayPathForNameWithIndexName;
const getResolvedBrackets = (resolvedName) => [...resolvedName.matchAll(/(\w+)\[(\d+)\]/g)].map((m) => ({
    prop: m[1] ?? '',
    index: parseInt(m[2] ?? '0', 10),
}));
const findNameWithIndexName = (fields, indexName) => {
    const indexNameWithBrackets = `{{${indexName}}}`;
    const stack = [...fields];
    while (stack.length > 0) {
        const current = stack.pop();
        if (current === null) {
            continue;
        }
        if (Array.isArray(current)) {
            stack.push(...current);
            continue;
        }
        if (typeof current !== 'object') {
            continue;
        }
        const name = 'name' in current ? current.name : undefined;
        if (name && name.includes(indexNameWithBrackets)) {
            return name;
        }
        stack.push(...Object.values(current).filter((v) => v !== null && typeof v === 'object'));
    }
    return undefined;
};
exports.findNameWithIndexName = findNameWithIndexName;
const getSpliceTarget = (nameWithIndexName, resolvedName, indexName) => {
    const staticPrefix = getStaticPrefixBeforeArrayProp(nameWithIndexName);
    const templateSegments = getSegmentsFromTemplate(nameWithIndexName);
    const placeholderIdx = templateSegments.findIndex((s) => s.type === 'placeholder' && s.placeholder === indexName);
    if (placeholderIdx < 0) {
        return undefined;
    }
    const resolved = getResolvedBrackets(resolvedName);
    const at = resolved[placeholderIdx];
    if (!at || Number.isNaN(at.index)) {
        return undefined;
    }
    const prefix = [];
    for (let i = 0; i < placeholderIdx; i++) {
        const part = resolved[i];
        if (!part) {
            return undefined;
        }
        prefix.push(`${part.prop}[${part.index}]`);
    }
    const dynamicPrefix = prefix.join('.');
    const combinedPrefix = [staticPrefix, dynamicPrefix].filter(Boolean).join('.');
    const arrayPath = combinedPrefix ? `${combinedPrefix}.${at.prop}` : at.prop;
    return {
        arrayPath,
        itemIndex: at.index,
    };
};
exports.getSpliceTarget = getSpliceTarget;
const findAllNames = (fields) => {
    const names = [];
    const stack = [fields];
    while (stack.length > 0) {
        const current = stack.pop();
        if (Array.isArray(current)) {
            stack.push(...current);
        }
        else if (current && typeof current === 'object') {
            const name = 'name' in current && current.name;
            if (typeof name === 'string') {
                names.push(name);
            }
            stack.push(...Object.values(current));
        }
    }
    return names;
};
exports.findAllNames = findAllNames;
const getValueByPath = (content, path) => {
    return (0, lodash_1.get)(content, path);
};
exports.getValueByPath = getValueByPath;
const isValueNotEmpty = (value) => {
    if (value === null)
        return false;
    if (typeof value === 'string')
        return value.trim() !== '';
    if (typeof value === 'boolean')
        return true;
    if (typeof value === 'number')
        return !Number.isNaN(value);
    if (Array.isArray(value))
        return value.length > 0;
    if (typeof value === 'object')
        return Object.keys(value).length > 0;
    return true;
};
const sectionHasContentData = (fields, content) => {
    if (!fields.length) {
        return false;
    }
    for (const field of fields) {
        if (typeof field !== 'object') {
            continue;
        }
        if (field.type === 'section') {
            if (field.index !== undefined) {
                const nameWithIndexName = (0, exports.findNameWithIndexName)(field.fields, field.index);
                const arrayPath = nameWithIndexName
                    ? (0, exports.getArrayPathForNameWithIndexName)(nameWithIndexName, field.index)
                    : undefined;
                const arr = arrayPath ? (0, exports.getValueByPath)(content, arrayPath) : undefined;
                if (Array.isArray(arr) && arr.length > 0)
                    return true;
            }
            else if ((0, exports.sectionHasContentData)(field.fields, content)) {
                return true;
            }
            continue;
        }
        if ('name' in field && field.name) {
            return isValueNotEmpty((0, exports.getValueByPath)(content, field.name));
        }
    }
    return false;
};
exports.sectionHasContentData = sectionHasContentData;
const collectSectionClearTargets = (fields) => {
    const arrayPaths = new Set();
    const scalarResets = [];
    const walk = (list) => {
        if (!list?.length) {
            return;
        }
        for (const field of list) {
            if (!field || typeof field !== 'object') {
                continue;
            }
            const f = field;
            const type = f.type;
            if (type === 'section') {
                const groupFields = f.fields;
                const placeholder = f.index;
                if (typeof placeholder === 'string' && Array.isArray(groupFields)) {
                    const templateName = (0, exports.findNameWithIndexName)(groupFields, placeholder);
                    if (templateName) {
                        const arrayPath = (0, exports.getArrayPathForNameWithIndexName)(templateName, placeholder);
                        if (arrayPath) {
                            arrayPaths.add(arrayPath);
                        }
                    }
                    walk(groupFields);
                }
                else {
                    walk(f.fields);
                }
                continue;
            }
            if (typeof f.name === 'string' && f.name.length > 0 && !f.name.includes('{{')) {
                if (type === 'segmentedRadioGroup' && Object.hasOwn(f, 'defaultValue')) {
                    scalarResets.push({ path: f.name, mode: 'set', value: f.defaultValue });
                }
                else {
                    scalarResets.push({ path: f.name, mode: 'unset' });
                }
            }
        }
    };
    walk(fields);
    return {
        arrayPaths: [...arrayPaths],
        scalarResets,
    };
};
exports.collectSectionClearTargets = collectSectionClearTargets;
const clearSectionFormContent = (fields, onUpdate) => {
    const { arrayPaths, scalarResets } = (0, exports.collectSectionClearTargets)(fields);
    const arraySorted = [...arrayPaths].sort((a, b) => b.length - a.length);
    for (const path of arraySorted) {
        onUpdate(path, undefined, { unset: true });
    }
    for (const item of scalarResets) {
        if (item.mode === 'set') {
            onUpdate(item.path, item.value);
        }
        else {
            onUpdate(item.path, undefined, { unset: true });
        }
    }
};
exports.clearSectionFormContent = clearSectionFormContent;
//# sourceMappingURL=fields.js.map
