/**
 * Backup Manager
 * Handles automatic and manual backup/restore of all user data
 */

class BackupManager {
    constructor() {
        this.backupPrefix = 'webGame-backup-';
        this.maxAutoBackups = 5; // Keep last 5 auto backups
        this.autoBackupInterval = 30 * 60 * 1000; // 30 minutes
        this.autoBackupTimer = null;
        
        this.init();
    }

    init() {
        console.log('🛡️ Backup Manager initialized');
        // Perform aggressive cleanup first
        this.performEmergencyCleanup();
        this.cleanupOldBackups();
        // Disable auto-backup to prevent quota issues
        // this.startAutoBackup();
        console.log('⚠️ Auto-backup disabled to prevent storage quota issues');
    }

    /**
     * Create a complete backup of all user data
     */
    createBackup(isAutomatic = false) {
        try {
            // Check storage usage before backup
            const currentUsage = this.calculateStorageUsage();
            const maxStorage = 5 * 1024 * 1024; // 5MB typical localStorage limit
            
            console.log(`📊 Current storage usage: ${(currentUsage / 1024 / 1024).toFixed(2)}MB`);
            
            if (currentUsage > maxStorage * 0.7) { // If over 70% usage
                console.warn('⚠️ Storage usage high, performing preemptive cleanup...');
                this.performEmergencyCleanup();
            }
            
            const timestamp = new Date().toISOString();
            const backupData = this.gatherAllUserData();
            
            // Check backup size and clean if too large
            const testBackup = {
                timestamp,
                version: '1.0',
                isAutomatic,
                data: backupData,
                metadata: {
                    totalItems: this.countDataItems(backupData),
                    userAgent: navigator.userAgent,
                    appVersion: this.getAppVersion()
                }
            };
            
            const backupJson = JSON.stringify(testBackup);
            const backupSize = new Blob([backupJson]).size;
            const maxSize = 1 * 1024 * 1024; // Reduced to 1MB limit for safety
            
            console.log(`📊 Backup size: ${(backupSize / 1024 / 1024).toFixed(2)}MB`);
            
            // Always clean photo data from backups to prevent quota issues
            console.log('🧹 Proactively cleaning photo data from backup...');
            backupData.capturedPhotos = this.cleanLargePhotoData(backupData.capturedPhotos);
            backupData.photoGallery = this.cleanLargePhotoData(backupData.photoGallery);
            backupData.verificationPhotos = this.cleanLargePhotoData(backupData.verificationPhotos);
            
            // Update backup after cleaning
            testBackup.data = backupData;
            testBackup.metadata.totalItems = this.countDataItems(backupData);
            testBackup.metadata.photosReduced = true;
            
            // Recalculate size after cleaning
            const cleanedSize = new Blob([JSON.stringify(testBackup)]).size;
            console.log(`📊 Cleaned backup size: ${(cleanedSize / 1024 / 1024).toFixed(2)}MB`);

            const backupKey = `${this.backupPrefix}${Date.now()}`;
            
            try {
                localStorage.setItem(backupKey, JSON.stringify(testBackup));
            } catch (storageError) {
                if (storageError.name === 'QuotaExceededError') {
                    console.warn('⚠️ Storage quota exceeded, performing emergency cleanup...');
                    this.performEmergencyCleanup();
                    
                    // Try again with minimal backup
                    const minimalBackup = this.createMinimalBackup(isAutomatic);
                    localStorage.setItem(backupKey, JSON.stringify(minimalBackup));
                } else {
                    throw storageError;
                }
            }
            
            console.log(`🛡️ ${isAutomatic ? 'Auto' : 'Manual'} backup created: ${backupKey}`);
            console.log(`📊 Backup contains ${testBackup.metadata.totalItems} data items`);
            
            return backupKey;
        } catch (error) {
            console.error('❌ Backup creation failed:', error);
            throw error;
        }
    }
    
    /**
     * Clean large photo data to reduce backup size
     */
    cleanLargePhotoData(photoDataString) {
        if (!photoDataString) return photoDataString;
        
        try {
            const photoData = JSON.parse(photoDataString);
            if (Array.isArray(photoData)) {
                // Keep only metadata, remove actual image data
                const cleanedData = photoData.map(photo => ({
                    ...photo,
                    data: photo.data ? '[IMAGE_DATA_REMOVED_FOR_BACKUP]' : photo.data,
                    dataUrl: photo.dataUrl ? '[IMAGE_DATA_REMOVED_FOR_BACKUP]' : photo.dataUrl
                }));
                return JSON.stringify(cleanedData);
            }
        } catch (error) {
            console.warn('⚠️ Error cleaning photo data:', error);
        }
        
        return photoDataString;
    }
    
    /**
     * Create minimal backup with only essential data
     */
    createMinimalBackup(isAutomatic = false) {
        const essentialData = {};
        
        // Only include essential game data, no photos
        const webGameData = localStorage.getItem('webGame-data');
        if (webGameData) {
            essentialData.webGameData = JSON.parse(webGameData);
        }
        
        essentialData.playerStats = localStorage.getItem('playerStats');
        essentialData.achievements = localStorage.getItem('achievements');
        essentialData.selectedTheme = localStorage.getItem('selectedTheme');
        essentialData.userPreferences = localStorage.getItem('userPreferences');
        essentialData.disabledTasks = localStorage.getItem('disabledTasks');
        
        return {
            timestamp: new Date().toISOString(),
            version: '1.0',
            isAutomatic,
            data: essentialData,
            metadata: {
                totalItems: this.countDataItems(essentialData),
                userAgent: navigator.userAgent,
                appVersion: this.getAppVersion(),
                isMinimal: true
            }
        };
    }
    
    /**
     * Emergency cleanup when storage quota is exceeded
     */
    performEmergencyCleanup() {
        try {
            console.log('🚨 Starting emergency storage cleanup...');
            
            // Delete ALL backups immediately
            const keys = Object.keys(localStorage);
            const backupKeys = keys.filter(key => key.startsWith(this.backupPrefix));
            backupKeys.forEach(key => localStorage.removeItem(key));
            console.log(`🧹 Emergency: Removed ${backupKeys.length} backups`);
            
            // Clean up ALL photos - don't keep any in localStorage
            localStorage.removeItem('verificationPhotos');
            localStorage.removeItem('capturedPhotos');
            localStorage.removeItem('photoGallery');
            console.log(`🧹 Emergency: Removed all photo data from localStorage`);
            
            // Clean up any old individual photo keys
            const photoKeys = keys.filter(key => 
                key.startsWith('verificationPhoto_') || 
                key.startsWith('capturedPhoto_') ||
                key.startsWith('photo_')
            );
            
            photoKeys.forEach(key => {
                const value = localStorage.getItem(key);
                if (value && value.startsWith('blob:')) {
                    URL.revokeObjectURL(value);
                }
                localStorage.removeItem(key);
            });
            console.log(`🧹 Emergency: Removed ${photoKeys.length} old photo keys`);
            
            // Calculate storage usage after cleanup
            const usage = this.calculateStorageUsage();
            console.log(`🧹 Emergency cleanup complete. Storage usage: ${(usage / 1024 / 1024).toFixed(2)}MB`);
            
        } catch (error) {
            console.error('❌ Emergency cleanup failed:', error);
        }
    }
    
    /**
     * Calculate approximate localStorage usage
     */
    calculateStorageUsage() {
        let totalSize = 0;
        try {
            for (let key in localStorage) {
                if (localStorage.hasOwnProperty(key)) {
                    const value = localStorage.getItem(key);
                    totalSize += new Blob([key + value]).size;
                }
            }
        } catch (error) {
            console.warn('⚠️ Could not calculate storage usage:', error);
        }
        return totalSize;
    }

    /**
     * Gather all user data from various storage systems
     */
    gatherAllUserData() {
        const data = {};

        // Main application data
        const webGameData = localStorage.getItem('webGame-data');
        if (webGameData) {
            data.webGameData = JSON.parse(webGameData);
        }

        // Media directories
        data.linkedImageDirectories = localStorage.getItem('linkedImageDirectories');
        data.linkedVideoDirectories = localStorage.getItem('linkedVideoDirectories');
        data.linkedAudioDirectories = localStorage.getItem('linkedAudioDirectories');

        // Video library data
        data.unifiedVideoLibrary = localStorage.getItem('unifiedVideoLibrary');
        data.backgroundVideos = localStorage.getItem('background-videos');
        data.taskVideos = localStorage.getItem('task-videos');
        data.rewardVideos = localStorage.getItem('reward-videos');
        data.punishmentVideos = localStorage.getItem('punishment-videos');

        // Player stats and achievements
        data.playerStats = localStorage.getItem('playerStats');
        data.achievements = localStorage.getItem('achievements');
        data.levelProgress = localStorage.getItem('levelProgress');

        // Photo gallery (metadata only, no image data)
        data.photoGallery = localStorage.getItem('photoGallery');
        data.capturedPhotos = localStorage.getItem('capturedPhotos');
        data.verificationPhotos = localStorage.getItem('verificationPhotos');

        // Custom content
        data.customMainTasks = localStorage.getItem('customMainTasks');
        data.customConsequenceTasks = localStorage.getItem('customConsequenceTasks');
        data.customImages = localStorage.getItem('customImages');
        data.disabledTasks = localStorage.getItem('disabledTasks');

        // Theme and preferences
        data.selectedTheme = localStorage.getItem('selectedTheme');
        data.gameTheme = localStorage.getItem('gameTheme');
        data.userPreferences = localStorage.getItem('userPreferences');

        // Audio settings
        data.audioSettings = localStorage.getItem('audioSettings');
        data.musicSettings = localStorage.getItem('musicSettings');

        // Game state (if exists)
        data.autoSaveGameState = localStorage.getItem('autoSaveGameState');
        data.lastSession = localStorage.getItem('lastSession');

        return data;
    }

    /**
     * Count total data items for metadata
     */
    countDataItems(data) {
        let count = 0;
        for (const key in data) {
            if (data[key] !== null) {
                count++;
                if (typeof data[key] === 'string') {
                    try {
                        const parsed = JSON.parse(data[key]);
                        if (Array.isArray(parsed)) {
                            count += parsed.length;
                        } else if (typeof parsed === 'object') {
                            count += Object.keys(parsed).length;
                        }
                    } catch (e) {
                        // Not JSON, just count as 1
                    }
                }
            }
        }
        return count;
    }

    /**
     * Get application version
     */
    getAppVersion() {
        return document.querySelector('meta[name="version"]')?.content || 'unknown';
    }

    /**
     * List all available backups
     */
    listBackups() {
        const backups = [];
        
        for (let i = 0; i < localStorage.length; i++) {
            const key = localStorage.key(i);
            if (key && key.startsWith(this.backupPrefix)) {
                try {
                    const backup = JSON.parse(localStorage.getItem(key));
                    backups.push({
                        key,
                        timestamp: backup.timestamp,
                        isAutomatic: backup.isAutomatic,
                        version: backup.version,
                        totalItems: backup.metadata?.totalItems || 0,
                        size: localStorage.getItem(key).length
                    });
                } catch (e) {
                    console.warn(`⚠️ Invalid backup found: ${key}`);
                }
            }
        }

        // Sort by timestamp (newest first)
        return backups.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
    }

    /**
     * Restore data from a backup
     */
    restoreBackup(backupKey, selective = null) {
        try {
            const backupData = localStorage.getItem(backupKey);
            if (!backupData) {
                throw new Error(`Backup ${backupKey} not found`);
            }

            const backup = JSON.parse(backupData);
            const data = backup.data;

            // Create a restore point before restoring
            const restorePointKey = this.createBackup(false);
            console.log(`🛡️ Restore point created: ${restorePointKey}`);

            let restoredCount = 0;

            // Restore all data or selective data
            for (const key in data) {
                if (data[key] !== null && (!selective || selective.includes(key))) {
                    if (key === 'webGameData') {
                        localStorage.setItem('webGame-data', JSON.stringify(data[key]));
                    } else {
                        localStorage.setItem(key, data[key]);
                    }
                    restoredCount++;
                }
            }

            console.log(`✅ Backup restored: ${restoredCount} items from ${backup.timestamp}`);
            console.log(`🔄 Restart the application to fully apply restored data`);
            
            return {
                success: true,
                restoredItems: restoredCount,
                backupTimestamp: backup.timestamp,
                restorePointKey
            };
            
        } catch (error) {
            console.error('❌ Backup restore failed:', error);
            throw error;
        }
    }

    /**
     * Export backup to file for external storage
     */
    async exportBackup(backupKey) {
        try {
            const backupData = localStorage.getItem(backupKey);
            if (!backupData) {
                throw new Error(`Backup ${backupKey} not found`);
            }

            const backup = JSON.parse(backupData);
            const filename = `webGame-backup-${backup.timestamp.replace(/[:.]/g, '-')}.json`;
            
            if (window.electronAPI && window.electronAPI.saveFile) {
                // Electron environment - use native file dialog
                const success = await window.electronAPI.saveFile(filename, backupData);
                if (success) {
                    console.log(`📁 Backup exported to file: ${filename}`);
                    return { success: true, filename };
                }
            } else {
                // Browser environment - download file
                const blob = new Blob([backupData], { type: 'application/json' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = filename;
                a.click();
                URL.revokeObjectURL(url);
                console.log(`📁 Backup downloaded: ${filename}`);
                return { success: true, filename };
            }
        } catch (error) {
            console.error('❌ Backup export failed:', error);
            throw error;
        }
    }

    /**
     * Import backup from file
     */
    async importBackup(file) {
        try {
            const text = await file.text();
            const backup = JSON.parse(text);
            
            // Validate backup structure
            if (!backup.timestamp || !backup.data) {
                throw new Error('Invalid backup file format');
            }

            // Create unique key for imported backup
            const importKey = `${this.backupPrefix}imported-${Date.now()}`;
            localStorage.setItem(importKey, text);
            
            console.log(`📥 Backup imported: ${importKey} from ${backup.timestamp}`);
            return {
                success: true,
                backupKey: importKey,
                timestamp: backup.timestamp,
                totalItems: backup.metadata?.totalItems || 0
            };
            
        } catch (error) {
            console.error('❌ Backup import failed:', error);
            throw error;
        }
    }

    /**
     * Delete a backup
     */
    deleteBackup(backupKey) {
        try {
            if (localStorage.getItem(backupKey)) {
                localStorage.removeItem(backupKey);
                console.log(`🗑️ Backup deleted: ${backupKey}`);
                return true;
            }
            return false;
        } catch (error) {
            console.error('❌ Backup deletion failed:', error);
            return false;
        }
    }

    /**
     * Start automatic backup timer
     */
    startAutoBackup() {
        if (this.autoBackupTimer) {
            clearInterval(this.autoBackupTimer);
        }

        this.autoBackupTimer = setInterval(() => {
            try {
                this.createBackup(true);
                this.cleanupOldBackups();
            } catch (error) {
                console.error('❌ Auto-backup failed:', error);
            }
        }, this.autoBackupInterval);

        console.log(`🕐 Auto-backup scheduled every ${this.autoBackupInterval / 60000} minutes`);
    }

    /**
     * Stop automatic backups
     */
    stopAutoBackup() {
        if (this.autoBackupTimer) {
            clearInterval(this.autoBackupTimer);
            this.autoBackupTimer = null;
            console.log('🛑 Auto-backup stopped');
        }
    }

    /**
     * Clean up old automatic backups
     */
    cleanupOldBackups(maxToKeep = null) {
        const backups = this.listBackups();
        const autoBackups = backups.filter(b => b.isAutomatic);
        const maxBackups = maxToKeep || this.maxAutoBackups;
        
        if (autoBackups.length > maxBackups) {
            const toDelete = autoBackups.slice(maxBackups);
            toDelete.forEach(backup => {
                this.deleteBackup(backup.key);
            });
            console.log(`🧹 Cleaned up ${toDelete.length} old auto-backups (keeping ${maxBackups})`);
        }
    }

    /**
     * Get storage usage for backups
     */
    getBackupStorageInfo() {
        const backups = this.listBackups();
        const totalSize = backups.reduce((sum, backup) => sum + backup.size, 0);
        const autoBackups = backups.filter(b => b.isAutomatic).length;
        const manualBackups = backups.filter(b => !b.isAutomatic).length;
        
        return {
            totalBackups: backups.length,
            autoBackups,
            manualBackups,
            totalSize,
            formattedSize: this.formatBytes(totalSize),
            backups
        };
    }

    /**
     * Format bytes to human readable format
     */
    formatBytes(bytes) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    /**
     * Emergency backup before risky operations
     */
    createEmergencyBackup(reason = 'Emergency backup') {
        try {
            const backupKey = this.createBackup(false);
            console.log(`🚨 Emergency backup created: ${reason}`);
            return backupKey;
        } catch (error) {
            console.error('❌ Emergency backup failed:', error);
            throw error;
        }
    }
}

// Export for use in other modules
window.BackupManager = BackupManager;