/**
 * Client-side cache management utility
 * Handles cache busting and version checking for the application
 */
class ClientCacheManager {
    constructor() {
        this.currentVersion = null;
        this.versionCheckInterval = null;
        this.storageKey = 'app-version';
        this.init();
    }

    /**
     * Initialize cache manager
     */
    init() {
        this.getCurrentVersion();
        this.startVersionChecking();
        this.setupBeforeUnload();
    }

    /**
     * Get current app version from meta tag or API
     */
    async getCurrentVersion() {
        try {
            // First try to get version from meta tag
            const metaVersion = document.querySelector('meta[name="app-version"]');
            if (metaVersion) {
                this.currentVersion = metaVersion.getAttribute('content');
                this.storeVersion(this.currentVersion);
                return this.currentVersion;
            }

            // Fallback to API call
            const response = await fetch('/api/version');
            if (response.ok) {
                const data = await response.json();
                this.currentVersion = data.version;
                this.storeVersion(this.currentVersion);
                return this.currentVersion;
            }
        } catch (error) {
            console.warn('Could not retrieve app version:', error);
        }
        return null;
    }

    /**
     * Store version in localStorage
     * @param {string} version - Version to store
     */
    storeVersion(version) {
        try {
            localStorage.setItem(this.storageKey, version);
        } catch (error) {
            // Ignore localStorage errors
        }
    }

    /**
     * Get stored version from localStorage
     * @returns {string|null} Stored version
     */
    getStoredVersion() {
        try {
            return localStorage.getItem(this.storageKey);
        } catch (error) {
            return null;
        }
    }

    /**
     * Check if app version has changed
     * @returns {boolean} True if version changed
     */
    async hasVersionChanged() {
        const storedVersion = this.getStoredVersion();
        const currentVersion = await this.getCurrentVersion();
        
        return storedVersion && currentVersion && storedVersion !== currentVersion;
    }

    /**
     * Force reload the page with cache busting
     */
    forceReload() {
        // Clear cache-related storage
        try {
            localStorage.removeItem(this.storageKey);
            sessionStorage.clear();
        } catch (error) {
            // Ignore errors
        }

        // Force reload with cache busting
        const url = new URL(window.location);
        url.searchParams.set('_cb', Date.now());
        window.location.replace(url.toString());
    }

    /**
     * Start periodic version checking
     */
    startVersionChecking() {
        // Check every 30 seconds
        this.versionCheckInterval = setInterval(async () => {
            try {
                if (await this.hasVersionChanged()) {
                    this.handleVersionChange();
                }
            } catch (error) {
                console.warn('Version check failed:', error);
            }
        }, 30000);
    }

    /**
     * Stop version checking
     */
    stopVersionChecking() {
        if (this.versionCheckInterval) {
            clearInterval(this.versionCheckInterval);
            this.versionCheckInterval = null;
        }
    }

    /**
     * Handle version change detection
     */
    handleVersionChange() {
        // Show update notification
        this.showUpdateNotification();
    }

    /**
     * Show update notification to user
     */
    showUpdateNotification() {
        // Remove existing notification
        const existingNotification = document.querySelector('.update-notification');
        if (existingNotification) {
            existingNotification.remove();
        }

        // Create notification element
        const notification = document.createElement('div');
        notification.className = 'update-notification';
        notification.innerHTML = `
            <div class="update-notification-content">
                <span class="update-message">🔄 A new version is available!</span>
                <button class="update-button" onclick="cacheManager.forceReload()">Reload Now</button>
                <button class="update-dismiss" onclick="this.closest('.update-notification').remove()">×</button>
            </div>
        `;

        // Add styles
        notification.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background: #4CAF50;
            color: white;
            padding: 15px;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
            z-index: 10000;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            animation: slideIn 0.3s ease-out;
        `;

        // Add animation styles
        const style = document.createElement('style');
        style.textContent = `
            @keyframes slideIn {
                from { transform: translateX(100%); opacity: 0; }
                to { transform: translateX(0); opacity: 1; }
            }
            .update-notification-content {
                display: flex;
                align-items: center;
                gap: 10px;
            }
            .update-button {
                background: rgba(255,255,255,0.2);
                border: 1px solid rgba(255,255,255,0.3);
                color: white;
                padding: 5px 10px;
                border-radius: 4px;
                cursor: pointer;
                font-size: 12px;
            }
            .update-button:hover {
                background: rgba(255,255,255,0.3);
            }
            .update-dismiss {
                background: none;
                border: none;
                color: white;
                cursor: pointer;
                font-size: 18px;
                padding: 0;
                margin-left: 5px;
            }
            .update-message {
                font-size: 14px;
            }
        `;
        
        document.head.appendChild(style);
        document.body.appendChild(notification);

        // Auto-dismiss after 10 seconds
        setTimeout(() => {
            if (notification && notification.parentNode) {
                notification.remove();
            }
        }, 10000);
    }

    /**
     * Setup beforeunload handler to check version on page refresh
     */
    setupBeforeUnload() {
        window.addEventListener('beforeunload', async () => {
            // Quick version check before unload
            try {
                if (await this.hasVersionChanged()) {
                    // Clear cached version to force fresh load
                    this.storeVersion(null);
                }
            } catch (error) {
                // Ignore errors during unload
            }
        });
    }

    /**
     * Manual cache clear function
     */
    clearCache() {
        try {
            // Clear localStorage
            localStorage.clear();
            // Clear sessionStorage
            sessionStorage.clear();
            
            // Clear service worker cache if available
            if ('serviceWorker' in navigator && 'caches' in window) {
                caches.keys().then(names => {
                    names.forEach(name => {
                        caches.delete(name);
                    });
                });
            }

            console.log('Cache cleared successfully');
            return true;
        } catch (error) {
            console.error('Failed to clear cache:', error);
            return false;
        }
    }

    /**
     * Get debug information
     * @returns {object} Debug info
     */
    getDebugInfo() {
        return {
            currentVersion: this.currentVersion,
            storedVersion: this.getStoredVersion(),
            versionCheckActive: !!this.versionCheckInterval,
            timestamp: new Date().toISOString()
        };
    }
}

// Initialize cache manager when DOM is ready
let cacheManager;

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => {
        cacheManager = new ClientCacheManager();
    });
} else {
    cacheManager = new ClientCacheManager();
}

// Make cache manager globally available for debugging
window.cacheManager = cacheManager;

// Export for module systems
if (typeof module !== 'undefined' && module.exports) {
    module.exports = ClientCacheManager;
}
