/**
 * Safari AJAX Handler with Timeout and Retry Logic
 * Provides robust AJAX handling for Safari browsers with automatic retry on failure
 * 
 * @package HVAC_Community_Events
 * @since 2.0.0
 */

var SafariAjaxHandler = (function() {
    'use strict';
    
    /**
     * Default configuration
     */
    var defaults = {
        timeout: 30000,        // 30 seconds
        maxRetries: 3,         // Maximum retry attempts
        retryDelay: 1000,      // Initial retry delay (exponential backoff)
        chunkSize: 100,        // Items per chunk for large datasets
        progressCallback: null // Optional progress callback
    };
    
    /**
     * Make AJAX request with retry logic
     * 
     * @param {string} action - WordPress AJAX action
     * @param {object} data - Request data
     * @param {object} options - Optional configuration
     * @returns {jQuery.Deferred} Promise object
     */
    function request(action, data, options) {
        var settings = jQuery.extend({}, defaults, options || {});
        var attemptCount = 0;
        var deferred = jQuery.Deferred();
        
        function makeRequest() {
            attemptCount++;
            
            console.log('[Safari AJAX] Attempt ' + attemptCount + ' for action: ' + action);
            
            // Add Safari-specific headers
            var ajaxOptions = {
                url: typeof hvac_find_trainer !== 'undefined' ? hvac_find_trainer.ajax_url : ajaxurl,
                type: 'POST',
                timeout: settings.timeout,
                data: jQuery.extend({
                    action: action,
                    nonce: typeof hvac_find_trainer !== 'undefined' ? hvac_find_trainer.nonce : '',
                    _safari_request: true,
                    _attempt: attemptCount
                }, data),
                xhrFields: {
                    withCredentials: true // Safari ITP compatibility
                },
                beforeSend: function(xhr) {
                    // Add custom headers for Safari
                    xhr.setRequestHeader('X-Safari-Request', 'true');
                    xhr.setRequestHeader('X-Request-Attempt', attemptCount.toString());
                }
            };
            
            jQuery.ajax(ajaxOptions)
                .done(function(response) {
                    console.log('[Safari AJAX] Success for action: ' + action);
                    deferred.resolve(response);
                })
                .fail(function(xhr, status, error) {
                    console.error('[Safari AJAX] Failed attempt ' + attemptCount + ':', status, error);
                    
                    // Check if we should retry
                    if (status === 'timeout' && attemptCount < settings.maxRetries) {
                        // Calculate exponential backoff delay
                        var delay = settings.retryDelay * Math.pow(2, attemptCount - 1);
                        
                        console.log('[Safari AJAX] Retrying after ' + delay + 'ms...');
                        
                        // Update progress if callback provided
                        if (typeof settings.progressCallback === 'function') {
                            settings.progressCallback({
                                status: 'retrying',
                                attempt: attemptCount,
                                maxAttempts: settings.maxRetries,
                                delay: delay
                            });
                        }
                        
                        // Retry after delay
                        setTimeout(function() {
                            makeRequest();
                        }, delay);
                    } else {
                        // Max retries reached or non-timeout error
                        var errorMsg = 'Request failed after ' + attemptCount + ' attempts: ' + error;
                        console.error('[Safari AJAX] ' + errorMsg);
                        
                        // Update progress if callback provided
                        if (typeof settings.progressCallback === 'function') {
                            settings.progressCallback({
                                status: 'failed',
                                error: errorMsg,
                                attempts: attemptCount
                            });
                        }
                        
                        deferred.reject(xhr, status, error);
                    }
                });
        }
        
        // Start the first request
        makeRequest();
        
        return deferred.promise();
    }
    
    /**
     * Process large datasets in chunks
     * 
     * @param {string} action - WordPress AJAX action
     * @param {array} items - Array of items to process
     * @param {object} options - Optional configuration
     * @returns {jQuery.Deferred} Promise object
     */
    function processChunked(action, items, options) {
        var settings = jQuery.extend({}, defaults, options || {});
        var deferred = jQuery.Deferred();
        var results = [];
        var chunks = [];
        
        // Split items into chunks
        for (var i = 0; i < items.length; i += settings.chunkSize) {
            chunks.push(items.slice(i, i + settings.chunkSize));
        }
        
        console.log('[Safari AJAX] Processing ' + chunks.length + ' chunks of ' + settings.chunkSize + ' items');
        
        var currentChunk = 0;
        
        function processNextChunk() {
            if (currentChunk >= chunks.length) {
                // All chunks processed
                console.log('[Safari AJAX] All chunks processed successfully');
                deferred.resolve(results);
                return;
            }
            
            var chunk = chunks[currentChunk];
            
            // Update progress if callback provided
            if (typeof settings.progressCallback === 'function') {
                settings.progressCallback({
                    status: 'processing',
                    current: currentChunk + 1,
                    total: chunks.length,
                    percentage: Math.round(((currentChunk + 1) / chunks.length) * 100)
                });
            }
            
            // Process current chunk
            request(action, { items: chunk }, settings)
                .done(function(response) {
                    results.push(response);
                    currentChunk++;
                    
                    // Process next chunk with small delay to prevent overload
                    setTimeout(processNextChunk, 100);
                })
                .fail(function(xhr, status, error) {
                    console.error('[Safari AJAX] Chunk processing failed:', error);
                    deferred.reject(xhr, status, error);
                });
        }
        
        // Start processing
        processNextChunk();
        
        return deferred.promise();
    }
    
    /**
     * Cancel all pending requests
     */
    function cancelAll() {
        // This would need to track active XHR objects
        console.log('[Safari AJAX] Cancelling all pending requests');
        // Implementation would track and abort active XHR requests
    }
    
    /**
     * Check if Safari browser
     */
    function isSafari() {
        return navigator.userAgent.indexOf('Safari') !== -1 && 
               navigator.userAgent.indexOf('Chrome') === -1 &&
               navigator.userAgent.indexOf('Chromium') === -1;
    }
    
    /**
     * Initialize Safari AJAX handler
     */
    function init() {
        if (!isSafari()) {
            console.log('[Safari AJAX] Not Safari browser, handler not needed');
            return false;
        }
        
        console.log('[Safari AJAX] Handler initialized for Safari browser');
        
        // Override jQuery.ajax for Safari if needed
        if (window.hvac_safari_ajax_override) {
            var originalAjax = jQuery.ajax;
            
            jQuery.ajax = function(options) {
                // Add Safari-specific defaults
                if (!options.timeout) {
                    options.timeout = defaults.timeout;
                }
                
                if (!options.xhrFields) {
                    options.xhrFields = {};
                }
                options.xhrFields.withCredentials = true;
                
                return originalAjax.call(this, options);
            };
            
            console.log('[Safari AJAX] jQuery.ajax override applied');
        }
        
        return true;
    }
    
    // Public API
    return {
        request: request,
        processChunked: processChunked,
        cancelAll: cancelAll,
        isSafari: isSafari,
        init: init,
        defaults: defaults
    };
})();

// Initialize on document ready
jQuery(document).ready(function() {
    SafariAjaxHandler.init();
    
    // Make globally available
    window.SafariAjaxHandler = SafariAjaxHandler;
});