"use strict";
/**
 * Schema Error Formatter
 * Provides user-friendly error messages for schema validation failures
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SchemaErrorFormatter = void 0;
const chalk_1 = __importDefault(require("chalk"));
class SchemaErrorFormatter {
    /**
     * Format a Zod error into user-friendly messages with examples
     */
    static format(error, source = 'workflow') {
        const formattedErrors = error.issues.map(issue => this.formatIssue(issue));
        let output = chalk_1.default.red.bold(`\n✖ Validation errors in ${source}:\n\n`);
        formattedErrors.forEach((error, index) => {
            output += chalk_1.default.yellow(`${index + 1}. ${error.path || 'Root'}\n`);
            output += `   ${chalk_1.default.dim('Error:')} ${error.message}\n`;
            if (error.suggestion) {
                output += `   ${chalk_1.default.cyan('→')} ${error.suggestion}\n`;
            }
            if (error.example) {
                output += `\n   ${chalk_1.default.dim(error.example.title + ':')}\n`;
                if (error.example.incorrect) {
                    output += chalk_1.default.red(`   ✗ ${error.example.incorrect}\n`);
                }
                output += chalk_1.default.green(`   ✓ ${error.example.correct}\n`);
            }
            output += '\n';
        });
        output += chalk_1.default.dim(`For more information, see: https://docs.bangstack.dev/workflows\n`);
        return output;
    }
    /**
     * Format a single Zod issue with context-aware examples
     */
    static formatIssue(issue) {
        const path = issue.path.join('.');
        let message = issue.message;
        let example;
        let suggestion;
        // Enhance messages based on path and error type
        if (issue.code === 'invalid_type') {
            const enhancedMessage = this.enhanceTypeError(path, issue);
            message = enhancedMessage.message;
            example = enhancedMessage.example;
            suggestion = enhancedMessage.suggestion;
        }
        else if (issue.code === 'invalid_enum_value') {
            const enhancedMessage = this.enhanceEnumError(path, issue);
            message = enhancedMessage.message;
            example = enhancedMessage.example;
            suggestion = enhancedMessage.suggestion;
        }
        else if (issue.code === 'too_small') {
            const enhancedMessage = this.enhanceMinError(path, issue);
            message = enhancedMessage.message;
            suggestion = enhancedMessage.suggestion;
        }
        else if (issue.code === 'custom') {
            // Custom errors from superRefine
            const enhancedMessage = this.enhanceCustomError(path, issue);
            message = enhancedMessage.message;
            example = enhancedMessage.example;
            suggestion = enhancedMessage.suggestion;
        }
        else if (issue.code === 'unrecognized_keys') {
            const enhancedMessage = this.enhanceUnrecognizedKeysError(path, issue);
            message = enhancedMessage.message;
            suggestion = enhancedMessage.suggestion;
        }
        return {
            path,
            message,
            example,
            suggestion,
        };
    }
    /**
     * Enhance type error messages
     */
    static enhanceTypeError(path, issue) {
        const received = issue.received;
        const expected = issue.expected;
        // Stack component type errors
        if (path.startsWith('stack.') && path.endsWith('.type')) {
            return {
                message: `Stack component type must be a string (received: ${received})`,
                suggestion: 'Use descriptive types like "frontend", "backend", "database", etc.',
                example: {
                    title: 'Example',
                    incorrect: 'type: 123',
                    correct: 'type: frontend',
                },
            };
        }
        // Technology field errors
        if (path.startsWith('stack.') && path.endsWith('.technology')) {
            return {
                message: `Technology must be a string (received: ${received})`,
                suggestion: 'Specify the framework or technology you want to use',
                example: {
                    title: 'Example',
                    incorrect: 'technology: true',
                    correct: 'technology: react',
                },
            };
        }
        // Workflow metadata errors
        if (path.startsWith('workflow.')) {
            const field = path.split('.')[1];
            return {
                message: `Workflow ${field} must be a ${expected} (received: ${received})`,
                suggestion: `Provide a valid ${field} value in the workflow metadata`,
                example: {
                    title: 'Example',
                    correct: `workflow:\n  ${field}: "your-value-here"`,
                },
            };
        }
        return {
            message: `Expected ${expected}, received ${received}`,
            suggestion: `Check the data type for ${path}`,
        };
    }
    /**
     * Enhance enum error messages with valid options
     */
    static enhanceEnumError(path, issue) {
        const received = issue.received;
        const options = issue.options || [];
        // HTTP method errors
        if (path.includes('.method')) {
            return {
                message: `Invalid HTTP method: "${received}"`,
                suggestion: `Use one of: ${options.join(', ')}`,
                example: {
                    title: 'Example',
                    incorrect: `method: get`,
                    correct: `method: GET`,
                },
            };
        }
        // Frontend framework errors
        if (path === 'technology.frontend.framework') {
            return {
                message: `Unsupported frontend framework: "${received}"`,
                suggestion: `Use one of the supported frameworks: ${options.join(', ')}`,
                example: {
                    title: 'Example',
                    incorrect: `framework: nextjs`,
                    correct: `framework: react  # Next.js uses React`,
                },
            };
        }
        // Backend framework errors
        if (path === 'technology.backend.framework') {
            return {
                message: `Unsupported backend framework: "${received}"`,
                suggestion: `Use one of the supported frameworks: ${options.join(', ')}`,
                example: {
                    title: 'Example for TypeScript',
                    correct: `framework: express  # or fastify, nestjs`,
                },
            };
        }
        // Database type errors
        if (path === 'technology.database.type') {
            return {
                message: `Unsupported database type: "${received}"`,
                suggestion: `Use one of the supported databases: ${options.join(', ')}`,
                example: {
                    title: 'Example',
                    correct: `database:\n  type: postgresql`,
                },
            };
        }
        return {
            message: `Invalid value: "${received}". Expected one of: ${options.join(', ')}`,
            suggestion: `Choose a valid option for ${path}`,
        };
    }
    /**
     * Enhance minimum length/value errors
     */
    static enhanceMinError(path, issue) {
        const minimum = issue.minimum;
        const type = issue.type;
        if (type === 'string') {
            if (path === 'workflow.id' || path === 'workflow.name' || path === 'workflow.version') {
                return {
                    message: `${path} cannot be empty`,
                    suggestion: `Provide a meaningful ${path.split('.')[1]} for your workflow`,
                };
            }
            return {
                message: `${path} must be at least ${minimum} character(s)`,
                suggestion: 'Provide a non-empty value',
            };
        }
        if (type === 'array') {
            return {
                message: `${path} must have at least ${minimum} item(s)`,
                suggestion: `Add at least one item to ${path}`,
            };
        }
        return {
            message: issue.message,
            suggestion: `Ensure ${path} meets the minimum requirement`,
        };
    }
    /**
     * Enhance custom validation errors
     */
    static enhanceCustomError(path, issue) {
        const message = issue.message || '';
        // Model reference errors
        if (message.includes('references undefined model')) {
            const match = message.match(/'([^']+)'/);
            const modelName = match ? match[1] : '';
            return {
                message,
                suggestion: `Define the "${modelName}" model in the models section first`,
                example: {
                    title: 'Example',
                    correct: `models:\n  ${modelName}:\n    description: "..."\n    fields:\n      id: { type: uuid }`,
                },
            };
        }
        // API endpoint auth/roles errors
        if (message.includes('auth: required but no roles specified')) {
            return {
                message,
                suggestion: 'Either specify allowed roles or change auth to "none"',
                example: {
                    title: 'Example with roles',
                    correct: `api:\n  endpoints:\n    - method: GET\n      path: /api/users\n      auth: required\n      roles: [admin, user]  # or [] for all authenticated`,
                },
            };
        }
        // Role validation errors
        if (message.includes('not defined in User model')) {
            const match = message.match(/role '([^']+)'/);
            const invalidRole = match ? match[1] : '';
            const validRolesMatch = message.match(/Valid roles: ([^)]+)/);
            const validRoles = validRolesMatch ? validRolesMatch[1] : '';
            return {
                message,
                suggestion: `Use one of the defined roles: ${validRoles}`,
                example: {
                    title: 'Define the role in User model first',
                    correct: `models:\n  User:\n    fields:\n      role:\n        type: enum\n        enum_values: [admin, user, ${invalidRole}]`,
                },
            };
        }
        // Stack component minimum
        if (message.includes('at least one stack component')) {
            return {
                message,
                suggestion: 'Define at least one component in the stack (frontend, backend, database, etc.)',
                example: {
                    title: 'Example minimal stack',
                    correct: `stack:\n  frontend:\n    type: frontend\n    technology: react`,
                },
            };
        }
        return {
            message,
        };
    }
    /**
     * Enhance unrecognized keys errors
     */
    static enhanceUnrecognizedKeysError(path, issue) {
        const keys = issue.keys || [];
        return {
            message: `Unrecognized field(s): ${keys.join(', ')}`,
            suggestion: `Remove or rename these fields. Check the documentation for valid field names.`,
        };
    }
    /**
     * Format a simple error without Zod (for custom validation)
     */
    static formatSimple(message, path, suggestion) {
        let output = chalk_1.default.red.bold(`\n✖ Validation error:\n\n`);
        if (path) {
            output += chalk_1.default.yellow(`${path}\n`);
        }
        output += `   ${chalk_1.default.dim('Error:')} ${message}\n`;
        if (suggestion) {
            output += `   ${chalk_1.default.cyan('→')} ${suggestion}\n`;
        }
        output += '\n';
        return output;
    }
    /**
     * Check if stack technologies are compatible with registered generators
     */
    static validateTechnologyCompatibility(technology, availableGenerators) {
        const warnings = [];
        // Check frontend
        if (technology?.frontend?.framework) {
            const framework = technology.frontend.framework;
            if (!availableGenerators.frontend.includes(framework)) {
                warnings.push(`Frontend framework "${framework}" may not have a registered generator. ` +
                    `Available: ${availableGenerators.frontend.join(', ')}`);
            }
        }
        // Check backend
        if (technology?.backend?.framework) {
            const framework = technology.backend.framework;
            const language = technology.backend.language;
            const _tech = `${language}/${framework}`;
            // This is a simplified check - actual implementation would check language/framework combo
            if (!availableGenerators.backend.includes(language)) {
                warnings.push(`Backend language "${language}" may not have a registered generator. ` +
                    `Available: ${availableGenerators.backend.join(', ')}`);
            }
        }
        // Check database
        if (technology?.database?.type) {
            const dbType = technology.database.type;
            // Map database types to ORMs
            const ormSupport = ['postgresql', 'mysql', 'sqlite', 'mongodb'].includes(dbType);
            if (!ormSupport && availableGenerators.database.length > 0) {
                warnings.push(`Database type "${dbType}" may require additional configuration`);
            }
        }
        return warnings;
    }
}
exports.SchemaErrorFormatter = SchemaErrorFormatter;
//# sourceMappingURL=schema-error-formatter.js.map