<?php
/**
 * HVAC Bundled Assets Manager
 * 
 * Modern asset management system using webpack-generated bundles
 * Replaces individual script loading with optimized bundles
 *
 * @package HVAC_Community_Events
 * @since 2.0.0
 */

if (!defined('ABSPATH')) {
    exit;
}

/**
 * HVAC Bundled Assets Manager
 */
class HVAC_Bundled_Assets {
    
    /**
     * Instance
     * 
     * @var HVAC_Bundled_Assets
     */
    private static $instance = null;
    
    /**
     * Asset version for cache busting
     * 
     * @var string
     */
    private $version;
    
    /**
     * Bundle manifest
     * 
     * @var array
     */
    private $manifest = array();
    
    /**
     * Get instance
     * 
     * @return HVAC_Bundled_Assets
     */
    public static function instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Constructor
     */
    private function __construct() {
        $this->version = HVAC_PLUGIN_VERSION;
        $this->load_manifest();
        $this->init_hooks();
    }
    
    /**
     * Load webpack manifest with integrity validation
     */
    private function load_manifest() {
        $manifest_path = HVAC_PLUGIN_DIR . 'assets/js/dist/manifest.json';
        if (!file_exists($manifest_path)) {
            return false;
        }
        
        // Add integrity validation
        $manifest_content = file_get_contents($manifest_path);
        if ($manifest_content === false) {
            error_log('HVAC: Failed to read manifest file');
            return false;
        }
        
        $manifest_hash = hash('sha256', $manifest_content);
        $expected_hash = get_option('hvac_manifest_hash');
        
        // Validate manifest integrity if hash exists
        if ($expected_hash && $expected_hash !== $manifest_hash) {
            error_log('HVAC: Manifest integrity check failed - possible tampering detected');
            return false;
        }
        
        $decoded_manifest = json_decode($manifest_content, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            error_log('HVAC: Invalid manifest JSON - ' . json_last_error_msg());
            return false;
        }
        
        // Validate manifest structure
        if (!is_array($decoded_manifest)) {
            error_log('HVAC: Manifest is not a valid array');
            return false;
        }
        
        // Store hash for future validation
        update_option('hvac_manifest_hash', $manifest_hash);
        
        $this->manifest = $decoded_manifest;
        return true;
    }
    
    /**
     * Initialize hooks
     */
    private function init_hooks() {
        // CRITICAL FIX: Only initialize bundled assets if NOT using legacy Scripts_Styles system
        // This prevents dual script loading that causes jQuery dependency conflicts
        if (!$this->should_use_legacy_scripts_system()) {
            add_action('wp_enqueue_scripts', array($this, 'enqueue_bundled_assets'), 5); // Load early
            add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_bundled_assets'), 5);
            add_action('wp_head', array($this, 'add_bundle_preload_hints'), 5);
        }
    }
    
    /**
     * Check if we should use legacy Scripts_Styles system instead of bundles
     * CRITICAL: Prevents dual script loading conflicts
     * 
     * @return bool
     */
    private function should_use_legacy_scripts_system() {
        // Force legacy mode if HVAC_FORCE_LEGACY_SCRIPTS is defined
        if (defined('HVAC_FORCE_LEGACY_SCRIPTS') && HVAC_FORCE_LEGACY_SCRIPTS) {
            return true;
        }
        
        // Use legacy system in development by default (safer for debugging)
        if (defined('WP_DEBUG') && WP_DEBUG && (!defined('HVAC_USE_BUNDLES') || !HVAC_USE_BUNDLES)) {
            return true;
        }
        
        // Safari browsers should use legacy system to prevent cascade issues
        if (class_exists('HVAC_Browser_Detection')) {
            $browser_detection = HVAC_Browser_Detection::instance();
            if ($browser_detection->is_safari_browser()) {
                error_log('HVAC Bundled Assets: Using legacy scripts for Safari compatibility');
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Check if we should use bundled assets
     * 
     * @return bool
     */
    private function should_use_bundled_assets() {
        // Don't use bundles if we should use legacy system
        if ($this->should_use_legacy_scripts_system()) {
            return false;
        }
        
        // Don't use bundles if forced to legacy mode
        if ($this->should_use_legacy_fallback()) {
            return false;
        }
        
        // Don't use bundles if manifest is empty (loading failed)
        if (empty($this->manifest)) {
            error_log('HVAC: Manifest is empty, falling back to legacy assets');
            return false;
        }
        
        // Use bundled assets in production or if HVAC_USE_BUNDLES is true
        return (!defined('WP_DEBUG') || !WP_DEBUG) || 
               (defined('HVAC_USE_BUNDLES') && HVAC_USE_BUNDLES);
    }
    
    /**
     * Check if current page needs HVAC assets
     * 
     * @return bool
     */
    private function is_plugin_page() {
        // Check if we're in a page template context
        if (defined('HVAC_IN_PAGE_TEMPLATE') && HVAC_IN_PAGE_TEMPLATE) {
            return true;
        }
        
        // Check using template loader if available
        if (class_exists('HVAC_Template_Loader')) {
            return HVAC_Template_Loader::is_plugin_template();
        }
        
        return false;
    }
    
    /**
     * Enqueue bundled frontend assets
     */
    public function enqueue_bundled_assets() {
        if (!$this->is_plugin_page() || !$this->should_use_bundled_assets()) {
            return;
        }
        
        $browser_detection = HVAC_Browser_Detection::instance();
        
        // Always load core bundle on plugin pages
        $this->enqueue_bundle('hvac-core');
        
        // Safari compatibility bundle for Safari browsers
        if ($browser_detection->is_safari_browser()) {
            $this->enqueue_bundle('hvac-safari-compat');
        }
        
        // Context-specific bundles based on page type
        if ($this->is_dashboard_page()) {
            $this->enqueue_bundle('hvac-dashboard');
        }
        
        if ($this->is_certificate_page()) {
            $this->enqueue_bundle('hvac-certificates');
        }
        
        if ($this->is_master_trainer_page()) {
            $this->enqueue_bundle('hvac-master');
        }
        
        if ($this->is_trainer_page()) {
            $this->enqueue_bundle('hvac-trainer');
        }
        
        if ($this->is_event_page()) {
            $this->enqueue_bundle('hvac-events');
        }
        
        // Localization for core bundle
        $this->localize_core_bundle();
    }
    
    /**
     * Enqueue admin bundled assets
     */
    public function enqueue_admin_bundled_assets() {
        if (!$this->should_use_bundled_assets()) {
            return;
        }
        
        // Admin bundle for WordPress admin areas
        if ($this->is_hvac_admin_page()) {
            $this->enqueue_bundle('hvac-admin');
        }
    }
    
    /**
     * Enqueue a specific bundle with validation and graceful degradation
     * 
     * @param string $bundle_name
     */
    private function enqueue_bundle($bundle_name) {
        $js_file = $this->get_bundle_file($bundle_name, 'js');
        $css_file = $this->get_bundle_file($bundle_name, 'css');
        
        // Validate and enqueue JavaScript bundle with security and performance monitoring
        if ($js_file) {
            $js_path = HVAC_PLUGIN_DIR . 'assets/js/dist/' . $js_file;
            if (file_exists($js_path)) {
                // Security: Validate file size is reasonable (prevent potential DoS)
                $file_size = filesize($js_path);
                if ($file_size > 1024 * 1024) { // 1MB limit
                    error_log("[HVAC] Bundle {$js_file} exceeds size limit ({$file_size} bytes) - falling back");
                    $this->enqueue_legacy_fallback($bundle_name);
                    return;
                }
                
                // Security: Validate filename contains only safe characters
                if (!preg_match('/^[a-zA-Z0-9._-]+$/', $js_file)) {
                    error_log("[HVAC] Invalid bundle filename: {$js_file} - falling back");
                    $this->enqueue_legacy_fallback($bundle_name);
                    return;
                }
                
                $version = filemtime($js_path); // Use file modification time for cache busting
                
                // CRITICAL FIX: Ensure jQuery is always loaded first
                wp_enqueue_script('jquery');
                
                wp_enqueue_script(
                    $bundle_name,
                    HVAC_PLUGIN_URL . 'assets/js/dist/' . $js_file,
                    array('jquery'),
                    $version,
                    true
                );
                
                // Add performance monitoring attributes
                $this->add_bundle_performance_monitoring($bundle_name);
                
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('[HVAC Bundled Assets] Loaded JS bundle: ' . $bundle_name . ' (' . round($file_size / 1024, 1) . 'KB)');
                }
            } else {
                error_log("[HVAC] Missing JS bundle: {$js_file} - falling back to legacy scripts");
                $this->enqueue_legacy_fallback($bundle_name);
            }
        }
        
        // Validate and enqueue CSS bundle if exists
        if ($css_file) {
            $css_path = HVAC_PLUGIN_DIR . 'assets/js/dist/' . $css_file;
            if (file_exists($css_path)) {
                wp_enqueue_style(
                    $bundle_name . '-style',
                    HVAC_PLUGIN_URL . 'assets/js/dist/' . $css_file,
                    array(),
                    filemtime($css_path)
                );
                
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('[HVAC Bundled Assets] Loaded CSS bundle: ' . $bundle_name);
                }
            } else {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log("[HVAC] Missing CSS bundle: {$css_file}");
                }
            }
        }
    }
    
    /**
     * Get bundle file path from manifest with chunk support
     * 
     * @param string $bundle_name
     * @param string $type js|css
     * @return string|null
     */
    private function get_bundle_file($bundle_name, $type = 'js') {
        $key = $bundle_name . '.' . $type;
        
        if (isset($this->manifest[$key])) {
            return $this->manifest[$key];
        }
        
        // Check for chunk files (lazy-loaded components)
        $chunk_key = $bundle_name . '.chunk.' . $type;
        if (isset($this->manifest[$chunk_key])) {
            return $this->manifest[$chunk_key];
        }
        
        // Fallback to expected filename pattern
        $suffix = (defined('WP_DEBUG') && WP_DEBUG) ? '' : '.min';
        return $bundle_name . '.bundle' . $suffix . '.' . $type;
    }
    
    /**
     * Get all chunk files for a bundle (for preloading)
     * 
     * @param string $bundle_name
     * @return array
     */
    private function get_bundle_chunks($bundle_name) {
        $chunks = [];
        
        // Look for all chunk files related to this bundle
        foreach ($this->manifest as $key => $filename) {
            // Match chunk files like "trainer-profile.chunk.js", "event-editing.chunk.js"
            if (preg_match("/({$bundle_name}-.+|.+-{$bundle_name})\.chunk\.(js|css)$/", $key)) {
                $chunks[$key] = $filename;
            }
        }
        
        return $chunks;
    }
    
    /**
     * Fallback to legacy individual scripts when bundles fail
     * 
     * @param string $bundle_name
     */
    private function enqueue_legacy_fallback($bundle_name) {
        // Check if we're already in too many error scenarios
        if ($this->should_use_legacy_fallback()) {
            return;
        }
        
        // Increment error count
        $error_count = get_transient('hvac_bundle_errors') ?: 0;
        set_transient('hvac_bundle_errors', $error_count + 1, HOUR_IN_SECONDS);
        
        // Map bundle names to legacy script methods
        $legacy_map = array(
            'hvac-core' => 'enqueue_core_scripts',
            'hvac-dashboard' => 'enqueue_dashboard_scripts',
            'hvac-certificates' => 'enqueue_certificate_scripts',
            'hvac-master' => 'enqueue_master_trainer_scripts',
            'hvac-trainer' => 'enqueue_trainer_scripts',
            'hvac-events' => 'enqueue_event_scripts',
            'hvac-admin' => 'enqueue_admin_scripts'
        );
        
        if (isset($legacy_map[$bundle_name]) && class_exists('HVAC_Scripts_Styles')) {
            $scripts_instance = HVAC_Scripts_Styles::instance();
            $method = $legacy_map[$bundle_name];
            
            if (method_exists($scripts_instance, $method)) {
                $scripts_instance->$method();
                error_log("[HVAC] Fallback activated for bundle: {$bundle_name}");
            }
        }
    }
    
    /**
     * Check if we should use legacy fallback due to too many errors
     * 
     * @return bool
     */
    private function should_use_legacy_fallback() {
        $error_count = get_transient('hvac_bundle_errors');
        if ($error_count > 5) {
            // Too many errors, use legacy for 1 hour
            set_transient('hvac_force_legacy', true, HOUR_IN_SECONDS);
            return true;
        }
        
        return get_transient('hvac_force_legacy');
    }
    
    /**
     * Localize core bundle with WordPress data and security monitoring
     */
    private function localize_core_bundle() {
        wp_localize_script('hvac-core', 'hvacBundleData', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('hvac_bundle_nonce'),
            'rest_url' => rest_url('hvac/v1/'),
            'current_user_id' => get_current_user_id(),
            'is_safari' => HVAC_Browser_Detection::instance()->is_safari_browser(),
            'debug' => defined('WP_DEBUG') && WP_DEBUG,
            'version' => $this->version,
            // Security monitoring configuration
            'security' => array(
                'report_errors' => true,
                'error_endpoint' => rest_url('hvac/v1/bundle-errors'),
                'performance_monitoring' => !defined('HVAC_DISABLE_PERF_MONITORING'),
                'max_load_time' => 5000, // 5 seconds
                'retry_attempts' => 2
            )
        ));
        
        // Add client-side error detection and performance monitoring
        $this->add_client_side_monitoring();
    }
    
    /**
     * Add client-side error detection and performance monitoring
     */
    private function add_client_side_monitoring() {
        $monitoring_script = "
        (function() {
            'use strict';
            
            var hvacSecurity = {
                errors: [],
                performance: {},
                
                // Report bundle loading errors
                reportError: function(error, bundle) {
                    if (!window.hvacBundleData || !window.hvacBundleData.security.report_errors) return;
                    
                    this.errors.push({
                        error: error,
                        bundle: bundle,
                        timestamp: Date.now(),
                        userAgent: navigator.userAgent.substring(0, 100), // Limit length for security
                        url: window.location.href
                    });
                    
                    // Report to server if REST API available
                    if (window.hvacBundleData.security.error_endpoint) {
                        this.sendErrorReport();
                    }
                },
                
                // Send error reports to server
                sendErrorReport: function() {
                    if (this.errors.length === 0) return;
                    
                    fetch(window.hvacBundleData.security.error_endpoint, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-WP-Nonce': window.hvacBundleData.nonce
                        },
                        body: JSON.stringify({
                            errors: this.errors.splice(0, 5), // Send max 5 errors at once
                            page: window.location.pathname,
                            version: window.hvacBundleData.version
                        })
                    }).catch(function(e) {
                        console.warn('HVAC: Failed to report bundle errors', e);
                    });
                },
                
                // Monitor bundle loading performance
                monitorPerformance: function(bundleName, startTime) {
                    if (!window.hvacBundleData.security.performance_monitoring) return;
                    
                    var loadTime = Date.now() - startTime;
                    this.performance[bundleName] = loadTime;
                    
                    var maxLoadTime = window.hvacBundleData.security.max_load_time || 5000;
                    if (loadTime > maxLoadTime) {
                        this.reportError('Bundle load time exceeded ' + maxLoadTime + 'ms (' + loadTime + 'ms)', bundleName);
                    }
                }
            };
            
            // Global error handler for script loading failures
            window.addEventListener('error', function(e) {
                if (e.target && e.target.tagName === 'SCRIPT' && e.target.src && e.target.src.includes('hvac')) {
                    var bundleName = e.target.src.match(/hvac-([^.]+)/) ? e.target.src.match(/hvac-([^.]+)/)[1] : 'unknown';
                    hvacSecurity.reportError('Script load failed: ' + e.message, 'hvac-' + bundleName);
                }
            });
            
            // Attach to global scope for bundle monitoring
            window.hvacSecurity = hvacSecurity;
            
            // Auto-report errors every 30 seconds if any exist
            setInterval(function() {
                if (hvacSecurity.errors.length > 0) {
                    hvacSecurity.sendErrorReport();
                }
            }, 30000);
        })();
        ";
        
        wp_add_inline_script('hvac-core', $monitoring_script, 'before');
    }
    
    /**
     * Add bundle preload hints for critical resources
     */
    public function add_bundle_preload_hints() {
        if (!$this->is_plugin_page() || !$this->should_use_bundled_assets()) {
            return;
        }
        
        // Always preload core bundle on plugin pages
        $this->add_preload_hint('hvac-core', 'script');
        
        // Context-specific preloading for critical bundles
        if ($this->is_dashboard_page()) {
            $this->add_preload_hint('hvac-dashboard', 'script');
        }
        
        if ($this->is_master_trainer_page()) {
            $this->add_preload_hint('hvac-master', 'script');
        }
        
        // Safari compatibility bundle for Safari browsers
        $browser_detection = HVAC_Browser_Detection::instance();
        if ($browser_detection->is_safari_browser()) {
            $this->add_preload_hint('hvac-safari-compat', 'script');
        }
    }
    
    /**
     * Add individual preload hint with security validation
     * 
     * @param string $bundle_name
     * @param string $type script|style
     */
    private function add_preload_hint($bundle_name, $type) {
        $file_type = $type === 'script' ? 'js' : 'css';
        $bundle_file = $this->get_bundle_file($bundle_name, $file_type);
        
        if (!$bundle_file) {
            return;
        }
        
        // Validate file exists and is safe
        $file_path = HVAC_PLUGIN_DIR . 'assets/js/dist/' . $bundle_file;
        if (!file_exists($file_path)) {
            return;
        }
        
        // Security: Validate filename contains only safe characters
        if (!preg_match('/^[a-zA-Z0-9._-]+$/', $bundle_file)) {
            error_log('HVAC: Invalid bundle filename for preload: ' . $bundle_file);
            return;
        }
        
        $bundle_url = esc_url(HVAC_PLUGIN_URL . 'assets/js/dist/' . $bundle_file);
        $as_attribute = $type === 'script' ? 'script' : 'style';
        
        // Add integrity hash for additional security
        $integrity_hash = base64_encode(hash('sha384', file_get_contents($file_path), true));
        
        echo '<link rel="preload" href="' . $bundle_url . '" as="' . $as_attribute . '" integrity="sha384-' . $integrity_hash . '" crossorigin="anonymous">' . "\n";
        
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log("[HVAC Bundled Assets] Preload hint added for: {$bundle_name}.{$file_type}");
        }
    }
    
    /**
     * Add performance monitoring attributes to bundle scripts
     * 
     * @param string $bundle_name
     */
    private function add_bundle_performance_monitoring($bundle_name) {
        // Add inline script to monitor bundle loading performance
        $monitoring_script = "
        (function() {
            var startTime = performance.now();
            var bundleName = '{$bundle_name}';
            
            // Monitor when this script finishes loading
            if (window.hvacSecurity && window.hvacSecurity.monitorPerformance) {
                document.addEventListener('DOMContentLoaded', function() {
                    window.hvacSecurity.monitorPerformance(bundleName, startTime);
                });
            }
            
            // Fallback error detection if hvacSecurity not loaded
            window.addEventListener('error', function(e) {
                if (e.target && e.target.src && e.target.src.includes(bundleName)) {
                    console.error('HVAC Bundle Error: Failed to load ' + bundleName);
                }
            });
        })();
        ";
        
        wp_add_inline_script($bundle_name, $monitoring_script, 'before');
    }
    
    /**
     * Page detection methods
     */
    private function is_dashboard_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists('HVAC_Scripts_Styles', 'instance') &&
               method_exists(HVAC_Scripts_Styles::instance(), 'is_dashboard_page') ?
               HVAC_Scripts_Styles::instance()->is_dashboard_page() : false;
    }
    
    private function is_certificate_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists('HVAC_Scripts_Styles', 'instance') &&
               method_exists(HVAC_Scripts_Styles::instance(), 'is_certificate_page') ?
               HVAC_Scripts_Styles::instance()->is_certificate_page() : false;
    }
    
    private function is_master_trainer_page() {
        return $this->is_pending_approvals_page() || 
               $this->is_master_events_page() ||
               $this->is_import_export_page() ||
               is_page('master-dashboard') ||
               strpos($_SERVER['REQUEST_URI'], 'master-trainer/') !== false;
    }
    
    private function is_trainer_page() {
        return $this->is_trainer_profile_page() ||
               $this->is_registration_page() ||
               strpos($_SERVER['REQUEST_URI'], '/trainer/') !== false;
    }
    
    private function is_event_page() {
        return $this->is_event_manage_page() ||
               $this->is_create_event_page() ||
               $this->is_edit_event_page() ||
               $this->is_organizers_page() ||
               $this->is_venues_page();
    }
    
    private function is_hvac_admin_page() {
        $screen = get_current_screen();
        return $screen && strpos($screen->id, 'hvac') !== false;
    }
    
    // Helper methods (delegate to existing HVAC_Scripts_Styles if available)
    private function is_pending_approvals_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists(HVAC_Scripts_Styles::instance(), 'is_pending_approvals_page') ?
               HVAC_Scripts_Styles::instance()->is_pending_approvals_page() : false;
    }
    
    private function is_master_events_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists(HVAC_Scripts_Styles::instance(), 'is_master_events_page') ?
               HVAC_Scripts_Styles::instance()->is_master_events_page() : false;
    }
    
    private function is_import_export_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists(HVAC_Scripts_Styles::instance(), 'is_import_export_page') ?
               HVAC_Scripts_Styles::instance()->is_import_export_page() : false;
    }
    
    private function is_trainer_profile_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists(HVAC_Scripts_Styles::instance(), 'is_trainer_profile_page') ?
               HVAC_Scripts_Styles::instance()->is_trainer_profile_page() : false;
    }
    
    private function is_registration_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists(HVAC_Scripts_Styles::instance(), 'is_registration_page') ?
               HVAC_Scripts_Styles::instance()->is_registration_page() : false;
    }
    
    private function is_event_manage_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists(HVAC_Scripts_Styles::instance(), 'is_event_manage_page') ?
               HVAC_Scripts_Styles::instance()->is_event_manage_page() : false;
    }
    
    private function is_create_event_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists(HVAC_Scripts_Styles::instance(), 'is_create_event_page') ?
               HVAC_Scripts_Styles::instance()->is_create_event_page() : false;
    }
    
    private function is_edit_event_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists(HVAC_Scripts_Styles::instance(), 'is_edit_event_page') ?
               HVAC_Scripts_Styles::instance()->is_edit_event_page() : false;
    }
    
    private function is_organizers_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists(HVAC_Scripts_Styles::instance(), 'is_organizers_page') ?
               HVAC_Scripts_Styles::instance()->is_organizers_page() : false;
    }
    
    private function is_venues_page() {
        return class_exists('HVAC_Scripts_Styles') && 
               method_exists(HVAC_Scripts_Styles::instance(), 'is_venues_page') ?
               HVAC_Scripts_Styles::instance()->is_venues_page() : false;
    }
}