import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { BlockCatalog } from '../blocks.js';
describe('BlockCatalog', () => {
    let catalog;
    beforeEach(() => {
        catalog = new BlockCatalog();
    });
    it('ships with core block types', () => {
        const all = catalog.getAll();
        expect(all.length).toBeGreaterThanOrEqual(10);
        const types = all.map((b) => b.type);
        expect(types).toContain('hero');
        expect(types).toContain('text');
        expect(types).toContain('image');
        expect(types).toContain('cards');
        expect(types).toContain('cta');
        expect(types).toContain('video');
        expect(types).toContain('gallery');
        expect(types).toContain('faq');
        expect(types).toContain('form');
        expect(types).toContain('code');
    });
    it('each core block has at least one variant', () => {
        for (const block of catalog.getAll()) {
            expect(block.variants.length).toBeGreaterThanOrEqual(1);
        }
    });
    it('get returns a block by type', () => {
        const hero = catalog.get('hero');
        expect(hero).toBeDefined();
        expect(hero.label).toBe('Hero');
    });
    it('get returns undefined for unknown type', () => {
        expect(catalog.get('nonexistent')).toBeUndefined();
    });
    it('each core block has fields keyed by name', () => {
        for (const block of catalog.getAll()) {
            expect(typeof block.fields).toBe('object');
            expect(Array.isArray(block.fields)).toBe(false);
            for (const [key, field] of Object.entries(block.fields)) {
                expect(key).toBeTruthy();
                expect(field.type).toBeTruthy();
            }
        }
    });
    it('register adds a custom block type', () => {
        const pricing = {
            type: 'pricing',
            label: 'Pricing',
            icon: 'DollarSign',
            variants: [{ name: 'table', label: 'Table', description: 'Pricing comparison table' }],
            fields: { title: { type: 'text', label: 'Title', required: true } },
        };
        catalog.register(pricing);
        expect(catalog.get('pricing')).toBeDefined();
        expect(catalog.get('pricing').label).toBe('Pricing');
    });
    it('register overwrites an existing block type', () => {
        const customHero = {
            type: 'hero',
            label: 'Custom Hero',
            icon: 'Star',
            variants: [{ name: 'custom', label: 'Custom', description: 'A custom hero variant' }],
            fields: { title: { type: 'text', label: 'Title', required: true } },
        };
        catalog.register(customHero);
        expect(catalog.get('hero').label).toBe('Custom Hero');
    });
    it('getVariant returns a specific variant', () => {
        const variant = catalog.getVariant('hero', 'centered');
        expect(variant).toBeDefined();
        expect(variant.label).toBe('Centered');
    });
    it('getVariant returns undefined for unknown variant', () => {
        expect(catalog.getVariant('hero', 'nonexistent')).toBeUndefined();
        expect(catalog.getVariant('nonexistent', 'centered')).toBeUndefined();
    });
    it('hero block has expected variants', () => {
        const hero = catalog.get('hero');
        const variantNames = hero.variants.map((v) => v.name);
        expect(variantNames).toContain('centered');
        expect(variantNames).toContain('split-image');
        expect(variantNames).toContain('video-bg');
        expect(variantNames).toContain('minimal');
    });
    describe('custom block discovery', () => {
        const original = globalThis.__actuateConfig;
        afterEach(() => {
            ;
            globalThis.__actuateConfig = original;
        });
        it('layers custom blocks from global config on top of core blocks', () => {
            ;
            globalThis.__actuateConfig = {
                pageBuilder: {
                    blocks: [
                        {
                            type: 'pricing',
                            label: 'Pricing',
                            icon: 'DollarSign',
                            variants: [{ name: 'table', label: 'Table', description: 'Pricing table' }],
                            fields: { title: { type: 'text', label: 'Title', required: true } },
                        },
                    ],
                },
            };
            const c = new BlockCatalog();
            expect(c.get('pricing')).toBeDefined();
            expect(c.get('hero')).toBeDefined();
        });
        it('explicit customBlocks override the global config', () => {
            ;
            globalThis.__actuateConfig = {
                pageBuilder: {
                    blocks: [
                        {
                            type: 'global-only',
                            label: 'Global Only',
                            icon: 'Globe',
                            variants: [{ name: 'a', label: 'A', description: 'A' }],
                            fields: {},
                        },
                    ],
                },
            };
            const c = new BlockCatalog({
                customBlocks: [
                    {
                        type: 'inline-only',
                        label: 'Inline',
                        icon: 'Code',
                        variants: [{ name: 'a', label: 'A', description: 'A' }],
                        fields: {},
                    },
                ],
            });
            expect(c.get('inline-only')).toBeDefined();
            expect(c.get('global-only')).toBeUndefined();
        });
        it('custom blocks override core blocks of the same type', () => {
            const c = new BlockCatalog({
                customBlocks: [
                    {
                        type: 'hero',
                        label: 'Brand Hero',
                        icon: 'Star',
                        variants: [{ name: 'brand', label: 'Brand', description: 'Brand hero' }],
                        fields: {},
                    },
                ],
            });
            expect(c.get('hero').label).toBe('Brand Hero');
        });
        it('includeCore: false returns only custom blocks', () => {
            const c = new BlockCatalog({
                includeCore: false,
                customBlocks: [
                    {
                        type: 'only',
                        label: 'Only',
                        icon: 'Square',
                        variants: [{ name: 'a', label: 'A', description: 'A' }],
                        fields: {},
                    },
                ],
            });
            expect(c.getAll()).toHaveLength(1);
            expect(c.get('only')).toBeDefined();
            expect(c.get('hero')).toBeUndefined();
        });
        it('ignores malformed entries in global config', () => {
            ;
            globalThis.__actuateConfig = {
                pageBuilder: {
                    blocks: [
                        null,
                        { label: 'No type' },
                        'string-not-block',
                        {
                            type: 'good',
                            label: 'Good',
                            icon: 'Check',
                            variants: [{ name: 'a', label: 'A', description: 'A' }],
                            fields: {},
                        },
                    ],
                },
            };
            const c = new BlockCatalog();
            expect(c.get('good')).toBeDefined();
        });
    });
});
//# sourceMappingURL=blocks.test.js.map