import { describe, it, expect } from 'vitest';
import { createId, findNode, findParent, addNode, removeNode, moveNode, updateNodeSettings, updateBlockData, createEmptyPage, createSection, createContainer, createRow, createColumn, createBlock, createSavedSectionRef, } from '../tree.js';
function makeTestPage() {
    return {
        id: 'page-1',
        type: 'page',
        children: [
            {
                id: 'sec-1',
                type: 'section',
                settings: {},
                children: [
                    {
                        id: 'con-1',
                        type: 'container',
                        settings: { maxWidth: '1200px' },
                        children: [
                            {
                                id: 'row-1',
                                type: 'row',
                                settings: { gap: '24px' },
                                children: [
                                    {
                                        id: 'col-1',
                                        type: 'column',
                                        settings: { width: 7 },
                                        children: [
                                            {
                                                id: 'blk-1',
                                                type: 'block',
                                                settings: { blockType: 'hero' },
                                                data: { title: 'Hello' },
                                            },
                                        ],
                                    },
                                    {
                                        id: 'col-2',
                                        type: 'column',
                                        settings: { width: 5 },
                                        children: [
                                            {
                                                id: 'blk-2',
                                                type: 'block',
                                                settings: { blockType: 'image' },
                                                data: { src: '/img.jpg' },
                                            },
                                        ],
                                    },
                                ],
                            },
                        ],
                    },
                ],
            },
        ],
    };
}
describe('findNode', () => {
    it('finds a deeply nested node by ID', () => {
        const page = makeTestPage();
        const node = findNode(page, 'blk-1');
        expect(node).toBeDefined();
        expect(node.id).toBe('blk-1');
        expect(node.type).toBe('block');
    });
    it('returns undefined for a non-existent ID', () => {
        const page = makeTestPage();
        expect(findNode(page, 'nope')).toBeUndefined();
    });
});
describe('findParent', () => {
    it('finds the parent of a nested node', () => {
        const page = makeTestPage();
        const parent = findParent(page, 'blk-1');
        expect(parent).toBeDefined();
        expect(parent.id).toBe('col-1');
    });
    it('returns undefined for the root node', () => {
        const page = makeTestPage();
        expect(findParent(page, 'page-1')).toBeUndefined();
    });
});
describe('addNode', () => {
    it('adds a node at the end of parent children', () => {
        const page = makeTestPage();
        const newBlock = {
            id: 'blk-3',
            type: 'block',
            settings: { blockType: 'text' },
            data: { content: 'New' },
        };
        const result = addNode(page, 'col-1', newBlock);
        const col1 = findNode(result, 'col-1');
        expect(col1.children).toHaveLength(2);
        expect(col1.children[1].id).toBe('blk-3');
    });
    it('adds a node at a specific index', () => {
        const page = makeTestPage();
        const newBlock = {
            id: 'blk-3',
            type: 'block',
            settings: { blockType: 'text' },
            data: { content: 'First' },
        };
        const result = addNode(page, 'col-1', newBlock, 0);
        const col1 = findNode(result, 'col-1');
        expect(col1.children[0].id).toBe('blk-3');
        expect(col1.children[1].id).toBe('blk-1');
    });
    it('does not mutate the original tree', () => {
        const page = makeTestPage();
        const newBlock = {
            id: 'blk-3',
            type: 'block',
            settings: { blockType: 'text' },
            data: {},
        };
        addNode(page, 'col-1', newBlock);
        const col1 = findNode(page, 'col-1');
        expect(col1.children).toHaveLength(1);
    });
    it('does not share references with the inserted node', () => {
        const page = makeTestPage();
        const newBlock = {
            id: 'blk-3',
            type: 'block',
            settings: { blockType: 'text' },
            data: { content: 'original' },
        };
        const result = addNode(page, 'col-1', newBlock);
        newBlock.data.content = 'mutated';
        const inserted = findNode(result, 'blk-3');
        expect(inserted.data.content).toBe('original');
    });
});
describe('removeNode', () => {
    it('removes a node from its parent', () => {
        const page = makeTestPage();
        const result = removeNode(page, 'blk-2');
        const col2 = findNode(result, 'col-2');
        expect(col2.children).toHaveLength(0);
    });
    it('does not mutate the original tree', () => {
        const page = makeTestPage();
        removeNode(page, 'blk-2');
        const col2 = findNode(page, 'col-2');
        expect(col2.children).toHaveLength(1);
    });
});
describe('moveNode', () => {
    it('moves a node from one parent to another', () => {
        const page = makeTestPage();
        const result = moveNode(page, 'blk-1', 'col-2');
        const col1 = findNode(result, 'col-1');
        const col2 = findNode(result, 'col-2');
        expect(col1.children).toHaveLength(0);
        expect(col2.children).toHaveLength(2);
        expect(col2.children[1].id).toBe('blk-1');
    });
    it('moves a node to a specific index', () => {
        const page = makeTestPage();
        const result = moveNode(page, 'blk-1', 'col-2', 0);
        const col2 = findNode(result, 'col-2');
        expect(col2.children[0].id).toBe('blk-1');
        expect(col2.children[1].id).toBe('blk-2');
    });
    it('does not mutate the original tree', () => {
        const page = makeTestPage();
        moveNode(page, 'blk-1', 'col-2');
        const col1 = findNode(page, 'col-1');
        const col2 = findNode(page, 'col-2');
        expect(col1.children).toHaveLength(1);
        expect(col2.children).toHaveLength(1);
    });
});
describe('updateNodeSettings', () => {
    it('merges new settings into a node', () => {
        const page = makeTestPage();
        const result = updateNodeSettings(page, 'sec-1', { background: '#fff' });
        const sec1 = findNode(result, 'sec-1');
        expect(sec1.settings.background).toBe('#fff');
    });
    it('does not mutate the original tree', () => {
        const page = makeTestPage();
        updateNodeSettings(page, 'sec-1', { background: '#fff' });
        const sec1 = findNode(page, 'sec-1');
        expect(sec1.settings.background).toBeUndefined();
    });
});
describe('updateBlockData', () => {
    it('merges new data into a block node', () => {
        const page = makeTestPage();
        const result = updateBlockData(page, 'blk-1', { title: 'Updated' });
        const blk1 = findNode(result, 'blk-1');
        expect(blk1.data.title).toBe('Updated');
    });
    it('preserves existing data fields', () => {
        const page = makeTestPage();
        const result = updateBlockData(page, 'blk-1', { subtitle: 'World' });
        const blk1 = findNode(result, 'blk-1');
        expect(blk1.data.title).toBe('Hello');
        expect(blk1.data.subtitle).toBe('World');
    });
});
describe('Factory functions', () => {
    it('createEmptyPage returns a valid page node', () => {
        const page = createEmptyPage();
        expect(page.type).toBe('page');
        expect(page.children).toEqual([]);
        expect(page.id).toMatch(/^node_/);
    });
    it('createSection returns a section with settings', () => {
        const section = createSection({ background: '#000' });
        expect(section.type).toBe('section');
        expect(section.settings.background).toBe('#000');
        expect(section.children).toEqual([]);
    });
    it('createContainer defaults maxWidth to 1200px', () => {
        const container = createContainer();
        expect(container.type).toBe('container');
        expect(container.settings.maxWidth).toBe('1200px');
    });
    it('createRow defaults gap and accepts columns', () => {
        const col = createColumn(6);
        const row = createRow([col]);
        expect(row.type).toBe('row');
        expect(row.settings.gap).toBe('24px');
        expect(row.children).toHaveLength(1);
        expect(row.children[0].id).toBe(col.id);
    });
    it('createColumn sets width', () => {
        const col = createColumn(8);
        expect(col.type).toBe('column');
        expect(col.settings.width).toBe(8);
        expect(col.children).toEqual([]);
    });
    it('createBlock sets blockType, variant, and data', () => {
        const block = createBlock('hero', 'centered', { title: 'Hi' });
        expect(block.type).toBe('block');
        expect(block.settings.blockType).toBe('hero');
        expect(block.settings.variant).toBe('centered');
        expect(block.data.title).toBe('Hi');
    });
    it('createSavedSectionRef sets refId', () => {
        const ref = createSavedSectionRef('saved-abc');
        expect(ref.type).toBe('savedSectionRef');
        expect(ref.settings.refId).toBe('saved-abc');
    });
    it('createId generates 100 unique IDs', () => {
        const ids = new Set();
        for (let i = 0; i < 100; i++) {
            ids.add(createId());
        }
        expect(ids.size).toBe(100);
    });
});
//# sourceMappingURL=tree.test.js.map