/**
 * WordPress Error Detection Utility
 * Detects critical WordPress errors that would block testing
 * 
 * Usage:
 *   const errorDetector = new WordPressErrorDetector(page);
 *   const error = await errorDetector.detectCriticalErrors();
 *   if (error) {
 *     throw new Error(`Critical WordPress Error: ${error.type} - ${error.message}`);
 *   }
 */

class WordPressErrorDetector {
    constructor(page) {
        this.page = page;
    }

    /**
     * Detect critical WordPress errors that would block testing
     * @returns {Object|null} Error object or null if no errors
     */
    async detectCriticalErrors() {
        try {
            // Check for fatal PHP errors
            const fatalError = await this.checkFatalPhpError();
            if (fatalError) return fatalError;

            // Check for database connection errors
            const dbError = await this.checkDatabaseError();
            if (dbError) return dbError;

            // Check for WordPress maintenance mode
            const maintenanceError = await this.checkMaintenanceMode();
            if (maintenanceError) return maintenanceError;

            // Check for plugin/theme errors
            const pluginError = await this.checkPluginThemeErrors();
            if (pluginError) return pluginError;

            // Check for HTTP error codes in page response
            const httpError = await this.checkHttpErrors();
            if (httpError) return httpError;

            return null;
        } catch (e) {
            return {
                type: 'DETECTION_ERROR',
                message: `Error while detecting WordPress errors: ${e.message}`,
                blocking: true
            };
        }
    }

    /**
     * Check for fatal PHP errors
     */
    async checkFatalPhpError() {
        const pageContent = await this.page.content();
        
        const fatalErrorPatterns = [
            /Fatal error:/i,
            /Parse error:/i,
            /Fatal Error:/i,
            /PHP Fatal error:/i,
            /Uncaught Error:/i,
            /Call to undefined function/i,
            /Maximum execution time exceeded/i,
            /Allowed memory size.*exhausted/i
        ];

        for (const pattern of fatalErrorPatterns) {
            if (pattern.test(pageContent)) {
                const match = pageContent.match(pattern);
                return {
                    type: 'FATAL_PHP_ERROR',
                    message: match ? match[0] : 'Fatal PHP error detected',
                    blocking: true,
                    details: this.extractErrorContext(pageContent, pattern)
                };
            }
        }

        return null;
    }

    /**
     * Check for database connection errors
     */
    async checkDatabaseError() {
        const pageContent = await this.page.content();
        
        const dbErrorPatterns = [
            /Error establishing a database connection/i,
            /Database connection error/i,
            /Can't connect to MySQL server/i,
            /Access denied for user/i,
            /MySQL server has gone away/i,
            /Lost connection to MySQL server/i
        ];

        for (const pattern of dbErrorPatterns) {
            if (pattern.test(pageContent)) {
                return {
                    type: 'DATABASE_ERROR',
                    message: 'Database connection error detected',
                    blocking: true,
                    details: this.extractErrorContext(pageContent, pattern)
                };
            }
        }

        return null;
    }

    /**
     * Check for WordPress maintenance mode
     */
    async checkMaintenanceMode() {
        const pageContent = await this.page.content();
        
        const maintenancePatterns = [
            /Briefly unavailable for scheduled maintenance/i,
            /The site is temporarily down for maintenance/i,
            /Maintenance mode is on/i
        ];

        for (const pattern of maintenancePatterns) {
            if (pattern.test(pageContent)) {
                return {
                    type: 'MAINTENANCE_MODE',
                    message: 'WordPress site is in maintenance mode',
                    blocking: true,
                    temporary: true
                };
            }
        }

        return null;
    }

    /**
     * Check for plugin/theme errors
     */
    async checkPluginThemeErrors() {
        const pageContent = await this.page.content();
        
        const pluginErrorPatterns = [
            /Plugin could not be activated because it triggered a fatal error/i,
            /The plugin generated.*characters of unexpected output/i,
            /There has been a critical error on this website/i,
            /Something went wrong/i
        ];

        for (const pattern of pluginErrorPatterns) {
            if (pattern.test(pageContent)) {
                return {
                    type: 'PLUGIN_THEME_ERROR',
                    message: 'Plugin or theme error detected',
                    blocking: true,
                    details: this.extractErrorContext(pageContent, pattern)
                };
            }
        }

        return null;
    }

    /**
     * Check for HTTP error responses
     */
    async checkHttpErrors() {
        try {
            const response = this.page.response();
            if (!response) return null;

            const status = response.status();
            if (status >= 500) {
                return {
                    type: 'HTTP_SERVER_ERROR',
                    message: `HTTP ${status} error`,
                    blocking: true,
                    statusCode: status,
                    statusText: response.statusText()
                };
            }

            if (status === 404) {
                const url = response.url();
                // Only consider 404 blocking for critical WordPress files
                if (url.includes('wp-admin') || url.includes('wp-login')) {
                    return {
                        type: 'HTTP_NOT_FOUND',
                        message: `Critical WordPress resource not found: ${url}`,
                        blocking: true,
                        statusCode: status
                    };
                }
            }

            return null;
        } catch (e) {
            return null; // Non-blocking if we can't check HTTP status
        }
    }

    /**
     * Extract error context from page content
     */
    extractErrorContext(content, pattern) {
        try {
            const match = content.match(pattern);
            if (!match) return null;

            const startIndex = match.index;
            const contextStart = Math.max(0, startIndex - 200);
            const contextEnd = Math.min(content.length, startIndex + 500);
            
            return content.substring(contextStart, contextEnd).replace(/\s+/g, ' ').trim();
        } catch (e) {
            return null;
        }
    }

    /**
     * Check if the current page has WordPress admin access
     */
    async checkWordPressAccess() {
        try {
            const title = await this.page.title();
            const url = this.page.url();
            
            // Check for WordPress indicators
            const isWordPress = title.toLowerCase().includes('wordpress') || 
                              await this.page.$('body.wp-admin') !== null ||
                              await this.page.$('body.login') !== null ||
                              url.includes('wp-admin') || 
                              url.includes('wp-login');

            if (!isWordPress) {
                return {
                    type: 'WORDPRESS_ACCESS_ERROR',
                    message: 'Unable to access WordPress - site may be down or not responding',
                    blocking: true,
                    url: url,
                    title: title
                };
            }

            return null;
        } catch (e) {
            return {
                type: 'ACCESS_CHECK_ERROR',
                message: `Error checking WordPress access: ${e.message}`,
                blocking: true
            };
        }
    }

    /**
     * Get comprehensive error report
     */
    async getErrorReport() {
        const errors = [];
        
        const criticalError = await this.detectCriticalErrors();
        if (criticalError) errors.push(criticalError);

        const accessError = await this.checkWordPressAccess();
        if (accessError) errors.push(accessError);

        return {
            hasErrors: errors.length > 0,
            blockingErrors: errors.filter(e => e.blocking),
            allErrors: errors,
            timestamp: new Date().toISOString(),
            url: this.page.url()
        };
    }
}

module.exports = WordPressErrorDetector;