/**
 * Schema Drift Guard
 * CI tool to detect schema drift between TypeScript (admin-spa) and PHP (SSR)
 *
 * This script runs as part of CI to ensure the section schema is consistent
 * across both the editor (TypeScript) and the SSR renderer (PHP).
 *
 * Usage:
 *   npx ts-node scripts/check-schema-drift.ts
 *   or
 *   node scripts/check-schema-drift.mjs
 */

import { readFileSync } from 'fs';
import { resolve } from 'path';

// Section types that must have matching renderers in PHP
const SECTION_TYPES = [
    'hero',
    'content',
    'image-text',
    'feature-grid',
    'cta-banner',
    'contact-form',
    'bento-category-grid',
    'product-carousel',
    'shoppable-image',
    'marquee-banner',
];

// Required props per section type (canonical schema)
const REQUIRED_PROPS: Record<string, string[]> = {
    'hero': ['title', 'subtitle', 'image', 'cta_text', 'cta_url'],
    'content': ['content', 'cta_text', 'cta_url'],
    'image-text': ['title', 'text', 'image', 'cta_text', 'cta_url'],
    'feature-grid': ['heading', 'items'],
    'cta-banner': ['title', 'text', 'button_text', 'button_url'],
    'contact-form': ['title', 'webhook_url', 'redirect_url'],
    'bento-category-grid': ['title', 'items'],
    'product-carousel': ['title', 'subtitle', 'cta_text', 'cta_url', 'source', 'limit'],
    'shoppable-image': ['title', 'subtitle', 'image', 'alt', 'hotspots'],
    'marquee-banner': ['text', 'separator', 'speed'],
};

// Section styles that must be supported by SSR
const REQUIRED_STYLES = [
    'backgroundType',
    'backgroundColor',
    'gradientFrom',
    'gradientTo',
    'gradientAngle',
    'backgroundImage',
    'backgroundOverlay',
    'paddingTop',
    'paddingBottom',
    'contentWidth',
    'heightPreset',
];

// Element styles per section type
const ELEMENT_STYLES: Record<string, string[]> = {
    'hero': ['title', 'subtitle', 'cta_text'],
    'content': ['heading', 'text', 'link', 'button', 'content'],
    'image-text': ['title', 'text', 'image', 'button'],
    'feature-grid': ['heading', 'feature_item'],
    'cta-banner': ['title', 'text', 'button_text'],
    'contact-form': ['title', 'button', 'fields'],
    'bento-category-grid': ['title'],
    'product-carousel': ['title', 'subtitle'],
    'shoppable-image': ['title'],
    'marquee-banner': [],
};

interface ValidationResult {
    passed: boolean;
    errors: string[];
    warnings: string[];
}

function validateSchemaConsistency(): ValidationResult {
    const errors: string[] = [];
    const warnings: string[] = [];

    // 1. Validate that all section types have required props
    SECTION_TYPES.forEach((type) => {
        const required = REQUIRED_PROPS[type] || [];
        if (required.length === 0) {
            warnings.push(`Section type '${type}' has no required props defined`);
        }
    });

    // 2. Validate PHP renderer file exists and has all renderers
    const phpSSRPath = resolve(__dirname, '../includes/Frontend/PageSSR.php');

    try {
        const phpContent = readFileSync(phpSSRPath, 'utf-8');

        // Check for render methods
        SECTION_TYPES.forEach((type) => {
            const methodName = `render_${type.replace(/-/g, '_')}`;
            const hasMethod = phpContent.includes(`public static function ${methodName}`);

            if (!hasMethod) {
                // Check if it falls back to generic
                const fallbackCheck = phpContent.includes(`render_${type.replace(/-/g, '_')}`);
                if (!fallbackCheck) {
                    warnings.push(`PHP SSR: No explicit renderer for '${type}', using generic fallback`);
                }
            }
        });

        // Check for required style handling in render methods
        const hasBackgroundType = phpContent.includes('$section_styles[\'backgroundType\']');
        const hasPaddingTop = phpContent.includes('$pt = $section_styles[\'paddingTop\']');
        const hasContentWidth = phpContent.includes('$content_width = $section_styles[\'contentWidth\']');

        if (!hasBackgroundType) {
            errors.push('PHP SSR: Missing backgroundType handling in section styles');
        }
        if (!hasPaddingTop) {
            errors.push('PHP SSR: Missing paddingTop handling in section styles');
        }
        if (!hasContentWidth) {
            warnings.push('PHP SSR: Missing contentWidth handling in section styles');
        }

    } catch (err) {
        errors.push(`Failed to read PHP SSR file: ${err}`);
    }

    // 3. Validate TypeScript schema file
    const tsSchemaPath = resolve(__dirname, '../admin-spa/src/routes/Appearance/Pages/schema/sectionSchema.ts');

    try {
        const tsContent = readFileSync(tsSchemaPath, 'utf-8');

        // Check that all section types are defined
        SECTION_TYPES.forEach((type) => {
            const schemaCheck = tsContent.includes(`'${type}':`);
            if (!schemaCheck) {
                errors.push(`TypeScript Schema: Missing definition for '${type}'`);
            }
        });

        // Check that feature-grid uses 'items' not 'features'
        const hasFeatureGridItems = tsContent.includes("items: { type: 'static', value: [] }");
        const hasFeatureGridFeatures = tsContent.includes("features:");

        if (hasFeatureGridFeatures && !hasFeatureGridItems) {
            errors.push('TypeScript Schema: feature-grid uses "features" instead of "items"');
        }

        // Check for defaultStyles with contentWidth
        const hasDefaultStyles = tsContent.includes('defaultStyles');
        const hasContentWidthDefault = tsContent.includes('contentWidth');

        if (!hasDefaultStyles) {
            warnings.push('TypeScript Schema: Missing defaultStyles definition');
        }
        if (!hasContentWidthDefault) {
            warnings.push('TypeScript Schema: Missing contentWidth in defaultStyles');
        }

    } catch (err) {
        errors.push(`Failed to read TypeScript Schema file: ${err}`);
    }

    // 4. Validate that props match between TS and PHP
    const propMismatches: string[] = [];

    SECTION_TYPES.forEach((type) => {
        const requiredProps = REQUIRED_PROPS[type] || [];

        requiredProps.forEach((prop) => {
            // Check PHP renders the prop
            const phpHasProp = phpContent?.includes(`$props['${prop}']`) ||
                              phpContent?.includes(`$props[\"${prop}\"]`);
            if (!phpHasProp) {
                propMismatches.push(`PHP render_${type}: Missing prop '${prop}' handling`);
            }
        });
    });

    if (propMismatches.length > 0) {
        warnings.push(...propMismatches);
    }

    return {
        passed: errors.length === 0,
        errors,
        warnings,
    };
}

function main() {
    console.log('🔍 WooNooW Schema Drift Check\n');
    console.log('========================================\n');

    const result = validateSchemaConsistency();

    if (result.warnings.length > 0) {
        console.log('⚠️  Warnings:');
        result.warnings.forEach((w) => console.log(`   - ${w}`));
        console.log('');
    }

    if (result.errors.length > 0) {
        console.log('❌ Errors (CI will fail):');
        result.errors.forEach((e) => console.log(`   - ${e}`));
        console.log('');
        console.log('❌ Schema drift detected! Please fix the errors above.');
        process.exit(1);
    }

    if (result.passed && result.warnings.length === 0) {
        console.log('✅ All checks passed! No schema drift detected.');
    } else if (result.passed) {
        console.log('✅ Core checks passed (warnings above are non-blocking).');
    }

    console.log('\n========================================');
    console.log('Schema Version: 1');
    console.log(`Section Types: ${SECTION_TYPES.length}`);
    console.log(`Required Styles: ${REQUIRED_STYLES.length}`);
}

// Run if called directly
main();