/**
 * Page Editor Schema Tests
 * Tests for canonical section schema and normalization
 */

import { describe, it, expect, beforeEach } from 'vitest';
import {
    SECTION_SCHEMAS,
    getSectionSchema,
    cloneDefaultProps,
    cloneDefaultStyles,
    normalizeFeatureGridProps,
} from '../../admin-spa/src/routes/Appearance/Pages/schema/sectionSchema';

describe('Section Schema', () => {
    describe('SECTION_SCHEMAS', () => {
        it('includes all required section types', () => {
            const expectedTypes = [
                'hero',
                'content',
                'image-text',
                'feature-grid',
                'cta-banner',
                'contact-form',
                'bento-category-grid',
                'product-carousel',
                'shoppable-image',
                'marquee-banner',
            ];

            expectedTypes.forEach((type) => {
                expect(SECTION_SCHEMAS).toHaveProperty(type);
            });
        });

        it('feature-grid uses items not features', () => {
            const featureGrid = SECTION_SCHEMAS['feature-grid'];
            expect(featureGrid.defaultProps).toHaveProperty('items');
            expect(featureGrid.defaultProps.items.type).toBe('static');
            expect(Array.isArray(featureGrid.defaultProps.items.value)).toBe(true);
            expect(featureGrid.defaultProps.items.value).toHaveLength(0);
        });

        it('hero section has correct default props', () => {
            const hero = SECTION_SCHEMAS['hero'];
            expect(hero.defaultProps).toHaveProperty('title');
            expect(hero.defaultProps).toHaveProperty('subtitle');
            expect(hero.defaultProps).toHaveProperty('image');
            expect(hero.defaultProps).toHaveProperty('cta_text');
            expect(hero.defaultProps).toHaveProperty('cta_url');
        });

        it('all sections have defaultStyles with contentWidth', () => {
            Object.values(SECTION_SCHEMAS).forEach((schema) => {
                expect(schema.defaultStyles).toBeDefined();
                expect(schema.defaultStyles).toHaveProperty('contentWidth');
            });
        });

        it('all sections have fields defined', () => {
            Object.values(SECTION_SCHEMAS).forEach((schema) => {
                expect(Array.isArray(schema.fields)).toBe(true);
                expect(schema.fields.length).toBeGreaterThan(0);
            });
        });
    });

    describe('getSectionSchema', () => {
        it('returns schema for valid section type', () => {
            const schema = getSectionSchema('hero');
            expect(schema).toBeDefined();
            expect(schema?.type).toBe('hero');
        });

        it('returns undefined for invalid section type', () => {
            const schema = getSectionSchema('nonexistent');
            expect(schema).toBeUndefined();
        });
    });

    describe('cloneDefaultProps', () => {
        it('returns props object for valid type', () => {
            const props = cloneDefaultProps('hero');
            expect(props).toHaveProperty('title');
            expect(props).toHaveProperty('subtitle');
        });

        it('returns empty object for invalid type', () => {
            const props = cloneDefaultProps('nonexistent');
            expect(Object.keys(props)).toHaveLength(0);
        });

        it('clones arrays correctly (no reference sharing)', () => {
            const props1 = cloneDefaultProps('feature-grid');
            const props2 = cloneDefaultProps('feature-grid');

            props1.items.value = [{ title: 'Test' }];
            expect(props2.items.value).toHaveLength(0);
        });
    });

    describe('cloneDefaultStyles', () => {
        it('returns default styles for valid type', () => {
            const styles = cloneDefaultStyles('hero');
            expect(styles).toHaveProperty('contentWidth');
        });

        it('returns undefined for invalid type', () => {
            const styles = cloneDefaultStyles('nonexistent');
            expect(styles).toBeUndefined();
        });
    });

    describe('normalizeFeatureGridProps', () => {
        it('leaves props unchanged when items exists', () => {
            const props = {
                items: [{ title: 'Feature 1' }],
                heading: 'Our Features',
            };

            const normalized = normalizeFeatureGridProps(props);

            expect(normalized.items).toHaveLength(1);
            expect(normalized.items[0].title).toBe('Feature 1');
        });

        it('copies features to items when items is undefined', () => {
            const props = {
                features: [{ title: 'Legacy Feature' }],
                heading: 'Our Features',
            };

            const normalized = normalizeFeatureGridProps(props);

            expect(normalized.items).toHaveLength(1);
            expect(normalized.items[0].title).toBe('Legacy Feature');
        });

        it('handles empty props', () => {
            const props = {};

            const normalized = normalizeFeatureGridProps(props);

            expect(normalized).toEqual({});
        });

        it('handles null/undefined input gracefully', () => {
            expect(normalizeFeatureGridProps(null)).toBeNull();
            expect(normalizeFeatureGridProps(undefined)).toBeUndefined();
        });
    });
});

describe('Section Editor Store Schema Integration', () => {
    // Test that the store uses the schema correctly
    it('section schema is compatible with store SectionProp interface', () => {
        const props = cloneDefaultProps('hero');

        // Check SectionProp structure
        expect(props.title).toHaveProperty('type');
        expect(props.title).toHaveProperty('value');

        // Ensure type is valid
        expect(props.title.type).toMatch(/^(static|dynamic)$/);
    });

    it('feature-grid default items is an empty array', () => {
        const props = cloneDefaultProps('feature-grid');

        expect(Array.isArray(props.items.value)).toBe(true);
        expect(props.items.value).toHaveLength(0);
    });
});

describe('Canvas Renderer Schema Integration', () => {
    // Test flattenSectionProps behavior with schema
    const flattenSectionProps = (section: any) => {
        const props = section.type === 'feature-grid'
            ? normalizeFeatureGridProps(section.props || {})
            : section.props || {};

        const flattened: Record<string, any> = {};
        for (const [key, value] of Object.entries(props)) {
            if (value && typeof value === 'object' && 'type' in value && 'value' in value) {
                flattened[key] = value.value;
            } else if (value && typeof value === 'object' && 'type' in value && 'source' in value) {
                flattened[key] = `[${value.source}]`;
            } else {
                flattened[key] = value;
            }
        }
        return flattened;
    };

    it('flattens static props correctly', () => {
        const section = {
            type: 'hero',
            props: {
                title: { type: 'static', value: 'Welcome' },
                subtitle: { type: 'static', value: 'Subtitle text' },
            },
        };

        const flattened = flattenSectionProps(section);

        expect(flattened.title).toBe('Welcome');
        expect(flattened.subtitle).toBe('Subtitle text');
    });

    it('flattens dynamic props with placeholder marker', () => {
        const section = {
            type: 'hero',
            props: {
                title: { type: 'dynamic', source: 'post_title' },
            },
        };

        const flattened = flattenSectionProps(section);

        expect(flattened.title).toBe('[post_title]');
    });

    it('flattens feature-grid items correctly', () => {
        const section = {
            type: 'feature-grid',
            props: {
                heading: { type: 'static', value: 'Features' },
                items: {
                    type: 'static',
                    value: [
                        { title: 'Feature 1', icon: 'Star' },
                        { title: 'Feature 2', icon: 'Heart' },
                    ],
                },
            },
        };

        const flattened = flattenSectionProps(section);

        expect(flattened.heading).toBe('Features');
        expect(Array.isArray(flattened.items)).toBe(true);
        expect(flattened.items).toHaveLength(2);
        expect(flattened.items[0].title).toBe('Feature 1');
    });

    it('handles mixed static and dynamic props', () => {
        const section = {
            type: 'image-text',
            props: {
                title: { type: 'dynamic', source: 'post_title' },
                text: { type: 'static', value: 'Static description' },
                image: { type: 'dynamic', source: 'post_featured_image' },
            },
        };

        const flattened = flattenSectionProps(section);

        expect(flattened.title).toBe('[post_title]');
        expect(flattened.text).toBe('Static description');
        expect(flattened.image).toBe('[post_featured_image]');
    });

    it('handles nested props without SectionProp wrapper', () => {
        const section = {
            type: 'feature-grid',
            props: {
                items: [
                    { title: 'Direct Item 1' },
                    { title: 'Direct Item 2' },
                ],
            },
        };

        const flattened = flattenSectionProps(section);

        expect(Array.isArray(flattened.items)).toBe(true);
        expect(flattened.items).toHaveLength(2);
    });
});