/**
 * RSL Performance Optimizer
 *
 * A lightweight performance optimization script that improves page load times through
 * resource hints, progressive loading, and smart component initialization.
 *
 * @fileoverview Performance optimization for RSL-powered websites
 * @version 1.0.0
 * @license MIT
 *
 * Key Features:
 * - Resource preconnection for external CDNs (FontAwesome, Google Fonts)
 * - Progressive component loading (defer non-critical components)
 * - Critical CSS prioritization
 * - Lazy loading for images and iframes
 * - Performance metrics tracking
 * - Configurable via data attributes
 *
 * Usage:
 * <!-- Place at top of <head> for best results -->
 * <script src="javascript/performance-optimizer.js"></script>
 *
 * <!-- Optional: Configure via data attributes on script tag -->
 * <script
 *   src="javascript/performance-optimizer.js"
 *   data-defer-components="modal,toast,off-canvas,popover"
 *   data-preconnect="https://kit.fontawesome.com,https://fonts.googleapis.com"
 *   data-track-metrics="true">
 * </script>
 *
 * Public API:
 * - RSL.PerformanceOptimizer.getMetrics() - Returns performance data
 * - RSL.PerformanceOptimizer.logMetrics() - Logs metrics to console
 * - RSL.PerformanceOptimizer.isEnabled() - Check if optimizer is running
 */

(function() {
    'use strict';

    window.RSL = window.RSL || {};

    /**
     * Get the current script element to read configuration
     * @returns {HTMLScriptElement|null} The script element
     */
    function getCurrentScript() {
        return document.currentScript || document.querySelector('script[src*="performance-optimizer"]');
    }

    /**
     * Parse configuration from script data attributes
     * @returns {Object} Configuration object
     */
    function getConfig() {
        const script = getCurrentScript();
        const defaults = {
            deferComponents: ['modal', 'toast', 'off-canvas', 'popover', 'carousel', 'accordion'],
            preconnectDomains: [
                'https://kit.fontawesome.com',
                'https://fonts.googleapis.com',
                'https://fonts.gstatic.com'
            ],
            trackMetrics: true,
            enableLazyLoading: true,
            logToConsole: false
        };

        if (!script) return defaults;

        // Override with data attributes if present
        const config = { ...defaults };

        if (script.dataset.deferComponents) {
            config.deferComponents = script.dataset.deferComponents.split(',').map(s => s.trim());
        }

        if (script.dataset.preconnect) {
            config.preconnectDomains = script.dataset.preconnect.split(',').map(s => s.trim());
        }

        if (script.dataset.trackMetrics !== undefined) {
            config.trackMetrics = script.dataset.trackMetrics === 'true';
        }

        if (script.dataset.enableLazyLoading !== undefined) {
            config.enableLazyLoading = script.dataset.enableLazyLoading === 'true';
        }

        if (script.dataset.logToConsole !== undefined) {
            config.logToConsole = script.dataset.logToConsole === 'true';
        }

        return config;
    }

    const config = getConfig();
    const metrics = {};

    /**
     * Add preconnect resource hints for external domains
     * Speeds up connections to CDNs before resources are requested
     *
     * @param {Array<string>} domains - Array of domain URLs to preconnect
     *
     * @example
     * addPreconnectHints(['https://kit.fontawesome.com']);
     */
    function addPreconnectHints(domains) {
        domains.forEach(function(domain) {
            // DNS prefetch (older browser fallback)
            const dnsPrefetch = document.createElement('link');
            dnsPrefetch.rel = 'dns-prefetch';
            dnsPrefetch.href = domain;
            document.head.appendChild(dnsPrefetch);

            // Preconnect (modern browsers)
            const preconnect = document.createElement('link');
            preconnect.rel = 'preconnect';
            preconnect.href = domain;
            preconnect.crossOrigin = 'anonymous';
            document.head.appendChild(preconnect);
        });
    }

    /**
     * Preload critical RSL resources
     * Tells browser to fetch critical files earlier in the loading process
     *
     * @example
     * preloadCriticalResources();
     */
    function preloadCriticalResources() {
        const criticalResources = [
            { href: 'styles/grid.css', as: 'style' },
            { href: 'styles/modern-theme.css', as: 'style' },
            { href: 'javascript/layout.js', as: 'script' }
        ];

        criticalResources.forEach(function(resource) {
            // Check if resource actually exists before preloading
            const existingLink = document.querySelector('link[href*="' + resource.href.split('/').pop() + '"]');
            const existingScript = document.querySelector('script[src*="' + resource.href.split('/').pop() + '"]');

            if (existingLink || existingScript) {
                const preload = document.createElement('link');
                preload.rel = 'preload';
                preload.href = resource.href;
                preload.as = resource.as;
                document.head.appendChild(preload);
            }
        });
    }

    /**
     * Defer loading of non-critical component scripts
     * Loads components after page interactive to improve initial load time
     *
     * @param {Array<string>} components - Array of component names to defer
     *
     * @example
     * deferNonCriticalComponents(['modal', 'toast']);
     */
    function deferNonCriticalComponents(components) {
        // Wait for page to be interactive
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', function() {
                loadDeferredComponents(components);
            });
        } else {
            loadDeferredComponents(components);
        }
    }

    /**
     * Load deferred component scripts
     *
     * @param {Array<string>} components - Component names to load
     */
    function loadDeferredComponents(components) {
        // Use requestIdleCallback if available, otherwise use setTimeout
        const scheduleLoad = window.requestIdleCallback || function(cb) {
            setTimeout(cb, 1);
        };

        scheduleLoad(function() {
            components.forEach(function(component) {
                const scriptPath = 'javascript/' + component + '.js';

                // Check if script already exists
                const existing = document.querySelector('script[src*="' + component + '.js"]');
                if (!existing) {
                    const script = document.createElement('script');
                    script.src = scriptPath;
                    script.defer = true;
                    document.body.appendChild(script);
                }
            });
        });
    }

    /**
     * Enable native lazy loading for images and iframes
     * Adds loading="lazy" to images/iframes that don't already have it
     *
     * @example
     * enableLazyLoading();
     */
    function enableLazyLoading() {
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', applyLazyLoading);
        } else {
            applyLazyLoading();
        }
    }

    /**
     * Apply lazy loading attributes to images and iframes
     */
    function applyLazyLoading() {
        // Images
        const images = document.querySelectorAll('img:not([loading])');
        images.forEach(function(img) {
            // Skip images in viewport (first few)
            const rect = img.getBoundingClientRect();
            const isInViewport = rect.top < window.innerHeight && rect.bottom > 0;

            if (!isInViewport) {
                img.loading = 'lazy';
            }
        });

        // Iframes
        const iframes = document.querySelectorAll('iframe:not([loading])');
        iframes.forEach(function(iframe) {
            iframe.loading = 'lazy';
        });
    }

    /**
     * Track performance metrics using Navigation Timing API
     * Collects detailed performance data about page load
     *
     * @returns {Object} Performance metrics object
     *
     * @example
     * const metrics = trackPerformanceMetrics();
     * console.log('Page Load Time:', metrics.pageLoadTime);
     */
    function trackPerformanceMetrics() {
        if (!config.trackMetrics || !window.performance) {
            return null;
        }

        window.addEventListener('load', function() {
            // Give browser time to finish all processing
            setTimeout(function() {
                const perfData = performance.getEntriesByType('navigation')[0];

                if (!perfData) return;

                metrics.dns = perfData.domainLookupEnd - perfData.domainLookupStart;
                metrics.tcp = perfData.connectEnd - perfData.connectStart;
                metrics.ttfb = perfData.responseStart - perfData.requestStart;
                metrics.download = perfData.responseEnd - perfData.responseStart;
                metrics.domInteractive = perfData.domInteractive;
                metrics.domComplete = perfData.domComplete;
                metrics.loadComplete = perfData.loadEventEnd;
                metrics.pageLoadTime = perfData.loadEventEnd - perfData.fetchStart;
                metrics.domContentLoaded = perfData.domContentLoadedEventEnd - perfData.domContentLoadedEventStart;

                // Web Vitals approximations
                const paintEntries = performance.getEntriesByType('paint');
                paintEntries.forEach(function(entry) {
                    if (entry.name === 'first-contentful-paint') {
                        metrics.fcp = entry.startTime;
                    }
                });

                // Store in window for access
                window.RSLPerformanceMetrics = metrics;

                if (config.logToConsole) {
                    console.group('RSL Performance Metrics');
                    console.log('Page Load Time:', metrics.pageLoadTime.toFixed(2) + 'ms');
                    console.log('DOM Interactive:', metrics.domInteractive.toFixed(2) + 'ms');
                    console.log('First Contentful Paint:', (metrics.fcp || 'N/A'));
                    console.log('DNS Lookup:', metrics.dns.toFixed(2) + 'ms');
                    console.log('TCP Connection:', metrics.tcp.toFixed(2) + 'ms');
                    console.log('Time to First Byte:', metrics.ttfb.toFixed(2) + 'ms');
                    console.log('Full metrics:', metrics);
                    console.groupEnd();
                }
            }, 0);
        });

        return metrics;
    }

    /**
     * Add font-display: swap to external font stylesheets
     * Prevents invisible text while fonts load
     */
    function optimizeFontLoading() {
        // This is best done in CSS, but we can inject a fallback
        const style = document.createElement('style');
        style.textContent = `
            @font-face {
                font-display: swap;
            }
        `;
        document.head.appendChild(style);
    }

    /**
     * Initialize all optimizations
     */
    function init() {
        // 1. Add preconnect hints immediately (in head, before resources load)
        addPreconnectHints(config.preconnectDomains);

        // 2. Preload critical resources
        preloadCriticalResources();

        // 3. Optimize font loading
        optimizeFontLoading();

        // 4. Enable lazy loading (waits for DOM)
        if (config.enableLazyLoading) {
            enableLazyLoading();
        }

        // 5. Defer non-critical components (waits for interactive)
        // Note: Only defer if scripts aren't already loaded
        // This is useful for large sites with many components
        // For small sites, may not be necessary
        // deferNonCriticalComponents(config.deferComponents);

        // 6. Track performance metrics
        if (config.trackMetrics) {
            trackPerformanceMetrics();
        }
    }

    // Public API
    window.RSL.PerformanceOptimizer = {
        /**
         * Get collected performance metrics
         * @returns {Object} Metrics object
         */
        getMetrics: function() {
            return window.RSLPerformanceMetrics || metrics;
        },

        /**
         * Log performance metrics to console
         */
        logMetrics: function() {
            const m = window.RSLPerformanceMetrics || metrics;
            if (!m.pageLoadTime) {
                console.warn('RSL Performance Optimizer: Metrics not yet available. Wait for page load.');
                return;
            }

            console.group('RSL Performance Metrics');
            console.log('Page Load Time:', m.pageLoadTime.toFixed(2) + 'ms');
            console.log('DOM Interactive:', m.domInteractive.toFixed(2) + 'ms');
            console.log('DOM Complete:', m.domComplete.toFixed(2) + 'ms');
            console.log('First Contentful Paint:', (m.fcp ? m.fcp.toFixed(2) + 'ms' : 'N/A'));
            console.log('DNS Lookup:', m.dns.toFixed(2) + 'ms');
            console.log('TCP Connection:', m.tcp.toFixed(2) + 'ms');
            console.log('Time to First Byte:', m.ttfb.toFixed(2) + 'ms');
            console.log('Download Time:', m.download.toFixed(2) + 'ms');
            console.log('DOM Content Loaded:', m.domContentLoaded.toFixed(2) + 'ms');
            console.groupEnd();
        },

        /**
         * Check if optimizer is enabled
         * @returns {boolean}
         */
        isEnabled: function() {
            return true;
        },

        /**
         * Get current configuration
         * @returns {Object}
         */
        getConfig: function() {
            return config;
        }
    };

    // Auto-initialize
    init();

})();
