import { pageNodeSchema } from './schema.js';
const MAX_DEPTH = 9;
export function validateTree(tree) {
    const errors = [];
    if (tree === null ||
        tree === undefined ||
        typeof tree !== 'object' ||
        !('type' in tree) ||
        tree.type !== 'page') {
        errors.push('Root node must be of type "page"');
        return { valid: false, errors };
    }
    const result = pageNodeSchema.safeParse(tree);
    if (!result.success) {
        for (const issue of result.error.issues) {
            const path = issue.path.length > 0 ? ` at ${issue.path.join('.')}` : '';
            errors.push(`${issue.message}${path}`);
        }
        return { valid: false, errors };
    }
    const pageNode = tree;
    checkColumnWidths(pageNode, errors);
    checkDepth(pageNode, 1, errors);
    checkBlockNoChildren(pageNode, errors);
    checkNestingRules(pageNode, errors);
    return { valid: errors.length === 0, errors };
}
function checkColumnWidths(node, errors) {
    if (!node || typeof node !== 'object')
        return;
    const n = node;
    if (n.type === 'row' && Array.isArray(n.children)) {
        const columns = n.children;
        const sum = columns.reduce((acc, col) => acc + (col.settings?.width ?? 0), 0);
        if (sum !== 12) {
            errors.push(`Row "${n.id}" columns sum to ${sum}, expected 12`);
        }
    }
    if ('children' in n && Array.isArray(n.children)) {
        for (const child of n.children) {
            checkColumnWidths(child, errors);
        }
    }
}
function checkDepth(node, depth, errors) {
    if (!node || typeof node !== 'object')
        return;
    const n = node;
    if (depth > MAX_DEPTH) {
        errors.push(`Maximum nesting depth of ${MAX_DEPTH} exceeded at node "${n.id}"`);
        return;
    }
    if ('children' in n && Array.isArray(n.children)) {
        for (const child of n.children) {
            checkDepth(child, depth + 1, errors);
        }
    }
}
function checkBlockNoChildren(node, errors) {
    if (!node || typeof node !== 'object')
        return;
    const n = node;
    if (n.type === 'block' &&
        'children' in n &&
        Array.isArray(n.children) &&
        n.children.length > 0) {
        errors.push(`Block node "${n.id}" must not have children`);
    }
    if ('children' in n && Array.isArray(n.children)) {
        for (const child of n.children) {
            checkBlockNoChildren(child, errors);
        }
    }
}
function checkNestingRules(node, errors) {
    if (!node || typeof node !== 'object')
        return;
    const n = node;
    if (n.type === 'page' && Array.isArray(n.children)) {
        for (const child of n.children) {
            if (child.type !== 'section' && child.type !== 'savedSectionRef') {
                errors.push(`Page node can only contain section or savedSectionRef children, found "${child.type}" ("${child.id}")`);
            }
        }
    }
}
//# sourceMappingURL=validate.js.map