/**
 * Unified Configuration Manager for HVAC Testing Framework
 * 
 * Provides centralized configuration management with environment-specific settings,
 * WordPress integration, and test execution parameters.
 * 
 * @package HVAC_Community_Events
 * @version 2.0.0
 * @created 2025-08-27
 */

const fs = require('fs');
const path = require('path');

class ConfigManager {
    /**
     * Configuration manager instance
     */
    static instance = null;
    
    /**
     * Get configuration manager instance (Singleton pattern)
     */
    static getInstance() {
        if (!ConfigManager.instance) {
            ConfigManager.instance = new ConfigManager();
        }
        return ConfigManager.instance;
    }
    
    constructor() {
        this.config = null;
        this.environment = process.env.NODE_ENV || process.env.HVAC_TEST_ENV || 'staging';
        this.loadConfiguration();
    }
    
    /**
     * Load configuration based on environment
     */
    loadConfiguration() {
        const configPath = path.resolve(__dirname, '../../environments/', `${this.environment}.config.js`);
        
        try {
            // Load environment-specific config
            const envConfig = require(configPath);
            
            // Load base configuration
            const baseConfig = this.getBaseConfiguration();
            
            // Merge configurations (environment overrides base)
            this.config = this.deepMerge(baseConfig, envConfig);
            
            console.log(`📋 Loaded configuration for environment: ${this.environment}`);
            
        } catch (error) {
            console.warn(`⚠️ Could not load environment config for ${this.environment}, using defaults`);
            this.config = this.getBaseConfiguration();
        }
    }
    
    /**
     * Get base configuration that applies to all environments
     */
    getBaseConfiguration() {
        return {
            // Test Framework Settings
            framework: {
                name: 'HVAC WordPress Testing Framework',
                version: '2.0.0',
                timeout: 30000,
                retries: 2,
                parallel: true,
                maxWorkers: 4,
                testDataIsolation: true,
                screenshotsOnFailure: true,
                videosOnFailure: true,
                reportFormat: 'html'
            },
            
            // WordPress Integration
            wordpress: {
                cliPath: 'wp',
                adminPath: '/wp-admin/',
                loginPath: '/wp-login.php',
                customLoginPath: '/training-login/',
                apiPath: '/wp-json/',
                databaseIsolation: true,
                flushRewriteRules: true,
                clearCache: true
            },
            
            // User Roles and Capabilities
            roles: {
                trainer: {
                    role: 'hvac_trainer',
                    capabilities: [
                        'read',
                        'manage_hvac_events',
                        'edit_hvac_profile',
                        'view_hvac_dashboard',
                        'manage_attendees',
                        'email_attendees'
                    ],
                    defaultPage: '/trainer/dashboard/'
                },
                masterTrainer: {
                    role: 'hvac_master_trainer',
                    capabilities: [
                        'read',
                        'manage_hvac_events',
                        'edit_hvac_profile',
                        'view_hvac_dashboard',
                        'manage_attendees',
                        'email_attendees',
                        'manage_all_events',
                        'approve_trainers',
                        'edit_trainer_profiles',
                        'manage_announcements',
                        'view_reports',
                        'manage_imports'
                    ],
                    defaultPage: '/master-trainer/master-dashboard/'
                },
                admin: {
                    role: 'administrator',
                    capabilities: ['manage_options'],
                    defaultPage: '/wp-admin/'
                }
            },
            
            // Browser Settings
            browser: {
                type: 'chromium',
                headless: process.env.CI === 'true',
                slowMo: process.env.CI === 'true' ? 0 : 100,
                viewport: {
                    width: 1280,
                    height: 720
                },
                mobileViewport: {
                    width: 375,
                    height: 667
                },
                args: [
                    '--disable-dev-shm-usage',
                    '--no-sandbox',
                    '--disable-setuid-sandbox'
                ]
            },
            
            // Screenshot and Video Settings
            media: {
                screenshotDir: './test-results/screenshots',
                videoDir: './test-results/videos',
                screenshotMode: 'only-on-failure',
                videoMode: 'retain-on-failure',
                quality: 80,
                fullPage: false
            },
            
            // Test Data Management
            testData: {
                seedData: true,
                cleanupAfterTests: true,
                isolateTransactions: true,
                backupDatabase: false,
                fixtures: {
                    users: './fixtures/test-users.json',
                    events: './fixtures/test-events.json',
                    venues: './fixtures/test-venues.json'
                }
            },
            
            // Selectors for stable element identification
            selectors: {
                dataTestIdAttribute: 'data-testid',
                roleAttribute: 'data-role',
                pageAttribute: 'data-page',
                formAttribute: 'data-form',
                buttonAttribute: 'data-action'
            },
            
            // Reporting
            reporting: {
                outputDir: './test-results/reports',
                formats: ['html', 'json', 'junit'],
                includeScreenshots: true,
                includeTimings: true,
                groupByCategory: true
            }
        };
    }
    
    /**
     * Get configuration value by path (e.g., 'browser.viewport.width')
     */
    get(path, defaultValue = null) {
        return this.getNestedValue(this.config, path.split('.'), defaultValue);
    }
    
    /**
     * Set configuration value by path
     */
    set(path, value) {
        this.setNestedValue(this.config, path.split('.'), value);
    }
    
    /**
     * Get environment name
     */
    getEnvironment() {
        return this.environment;
    }
    
    /**
     * Get full configuration object
     */
    getAll() {
        return { ...this.config };
    }
    
    /**
     * Get user configuration for specific role
     */
    getUserConfig(role) {
        const roleConfig = this.get(`roles.${role}`);
        const envConfig = this.get(`environments.users.${role}`);
        
        return {
            ...roleConfig,
            ...envConfig
        };
    }
    
    /**
     * Get WordPress CLI configuration
     */
    getWpCliConfig() {
        return {
            path: this.get('wordpress.cliPath'),
            url: this.get('app.baseUrl'),
            dbPrefix: this.get('database.prefix', 'wp_'),
            adminUser: this.get('environments.users.admin.username'),
            adminEmail: this.get('environments.users.admin.email')
        };
    }
    
    /**
     * Get browser launch configuration
     */
    getBrowserConfig() {
        return {
            ...this.get('browser'),
            timeout: this.get('framework.timeout'),
            actionTimeout: this.get('framework.timeout') * 0.75
        };
    }
    
    /**
     * Check if feature is enabled
     */
    isFeatureEnabled(feature) {
        return this.get(`features.${feature}`, false);
    }
    
    /**
     * Get environment-specific database configuration
     */
    getDatabaseConfig() {
        return this.get('database', {});
    }
    
    /**
     * Get test execution parameters
     */
    getExecutionConfig() {
        return {
            timeout: this.get('framework.timeout'),
            retries: this.get('framework.retries'),
            parallel: this.get('framework.parallel'),
            maxWorkers: this.get('framework.maxWorkers'),
            globalTimeout: this.get('framework.timeout') * 10
        };
    }
    
    /**
     * Validate configuration completeness
     */
    validate() {
        const required = [
            'app.baseUrl',
            'environments.users.trainer',
            'environments.users.masterTrainer'
        ];
        
        const missing = required.filter(path => this.get(path) === null);
        
        if (missing.length > 0) {
            throw new Error(`Missing required configuration: ${missing.join(', ')}`);
        }
        
        return true;
    }
    
    /**
     * Deep merge two configuration objects
     */
    deepMerge(target, source) {
        const result = { ...target };
        
        for (const key in source) {
            if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
                result[key] = this.deepMerge(target[key] || {}, source[key]);
            } else {
                result[key] = source[key];
            }
        }
        
        return result;
    }
    
    /**
     * Get nested value from object by path array
     */
    getNestedValue(obj, path, defaultValue) {
        let current = obj;
        
        for (const key of path) {
            if (current === null || current === undefined || !current.hasOwnProperty(key)) {
                return defaultValue;
            }
            current = current[key];
        }
        
        return current;
    }
    
    /**
     * Set nested value in object by path array
     */
    setNestedValue(obj, path, value) {
        let current = obj;
        
        for (let i = 0; i < path.length - 1; i++) {
            const key = path[i];
            if (!current[key] || typeof current[key] !== 'object') {
                current[key] = {};
            }
            current = current[key];
        }
        
        current[path[path.length - 1]] = value;
    }
    
    /**
     * Export configuration to file for debugging
     */
    exportToFile(filePath = null) {
        const outputPath = filePath || path.resolve('./test-results/config-export.json');
        const configData = {
            environment: this.environment,
            timestamp: new Date().toISOString(),
            config: this.config
        };
        
        fs.writeFileSync(outputPath, JSON.stringify(configData, null, 2));
        console.log(`📁 Configuration exported to: ${outputPath}`);
        
        return outputPath;
    }
}

// Export singleton instance
module.exports = ConfigManager.getInstance();