/**
 * Storage Manager
 * Handles localStorage persistence and user preferences
 */

import { formatBytes } from './utils.js';

export class StorageManager {
    constructor() {
        this.prefix = 'vna_dashboard_';
        this.isAvailable = this.checkAvailability();

        // Storage keys
        this.keys = {
            preferences: 'preferences',
            chartData: 'chart_data',
            session: 'session_data',
            debug: 'debug_info'
        };

        console.log(` Storage Manager initialized (${this.isAvailable ? 'available' : 'not available'})`);
    }

    /**
     * Check if localStorage is available
     */
    checkAvailability() {
        try {
            const test = '__storage_test__';
            localStorage.setItem(test, test);
            localStorage.removeItem(test);
            return true;
        } catch (e) {
            console.warn('localStorage not available:', e.message);
            return false;
        }
    }

    /**
     * Get full storage key with prefix
     */
    getKey(key) {
        return `${this.prefix}${key}`;
    }

    /**
     * Save data to localStorage
     */
    async save(key, data) {
        if (!this.isAvailable) {
            console.warn('Storage not available, cannot save:', key);
            return false;
        }

        try {
            const serialized = JSON.stringify({
                data,
                timestamp: Date.now(),
                version: '1.0'
            });

            localStorage.setItem(this.getKey(key), serialized);
            console.log(` Saved to storage: ${key}`);
            return true;

        } catch (error) {
            console.error('Failed to save to storage:', error);

            // Handle quota exceeded error
            if (error.name === 'QuotaExceededError') {
                console.log('Storage quota exceeded, cleaning up...');
                this.cleanup();

                // Try again after cleanup
                try {
                    localStorage.setItem(this.getKey(key), serialized);
                    console.log(` Saved to storage after cleanup: ${key}`);
                    return true;
                } catch (retryError) {
                    console.error('Still failed after cleanup:', retryError);
                }
            }

            return false;
        }
    }

    /**
     * Load data from localStorage
     */
    async load(key) {
        if (!this.isAvailable) {
            console.warn('Storage not available, cannot load:', key);
            return null;
        }

        try {
            const serialized = localStorage.getItem(this.getKey(key));
            if (!serialized) {
                return null;
            }

            const parsed = JSON.parse(serialized);

            // Validate structure
            if (!parsed.data || !parsed.timestamp) {
                console.warn('Invalid storage data format:', key);
                this.remove(key); // Clean up invalid data
                return null;
            }

            console.log(` Loaded from storage: ${key} (${new Date(parsed.timestamp).toLocaleString()})`);
            return parsed.data;

        } catch (error) {
            console.error('Failed to load from storage:', error);
            this.remove(key); // Clean up corrupted data
            return null;
        }
    }

    /**
     * Remove data from localStorage
     */
    async remove(key) {
        if (!this.isAvailable) return false;

        try {
            localStorage.removeItem(this.getKey(key));
            console.log(` Removed from storage: ${key}`);
            return true;
        } catch (error) {
            console.error('Failed to remove from storage:', error);
            return false;
        }
    }

    /**
     * Check if key exists in storage
     */
    async exists(key) {
        if (!this.isAvailable) return false;

        try {
            return localStorage.getItem(this.getKey(key)) !== null;
        } catch (error) {
            console.error('Failed to check storage existence:', error);
            return false;
        }
    }

    /**
     * Save user preferences
     */
    async savePreferences(preferences) {
        const data = {
            ...preferences,
            lastUpdated: Date.now()
        };

        return await this.save(this.keys.preferences, data);
    }

    /**
     * Load user preferences
     */
    async getPreferences() {
        return await this.load(this.keys.preferences);
    }

    /**
     * Save chart data for offline viewing
     */
    async saveChartData(chartData) {
        // Limit size to prevent storage overflow
        const maxCharts = 10;
        const limitedData = {};

        const chartNames = Object.keys(chartData).slice(-maxCharts);
        chartNames.forEach(name => {
            // Keep only last 100 data points per chart
            const data = chartData[name];
            if (Array.isArray(data)) {
                limitedData[name] = data.slice(-100);
            } else {
                limitedData[name] = data;
            }
        });

        return await this.save(this.keys.chartData, limitedData);
    }

    /**
     * Load saved chart data
     */
    async getChartData() {
        return await this.load(this.keys.chartData);
    }

    /**
     * Save session data (temporary data that expires)
     */
    async saveSession(sessionData) {
        const data = {
            ...sessionData,
            expiresAt: Date.now() + (24 * 60 * 60 * 1000) // 24 hours
        };

        return await this.save(this.keys.session, data);
    }

    /**
     * Load session data (with expiration check)
     */
    async getSession() {
        const data = await this.load(this.keys.session);

        if (data && data.expiresAt) {
            if (Date.now() > data.expiresAt) {
                console.log('Session data expired, removing...');
                await this.remove(this.keys.session);
                return null;
            }
        }

        return data;
    }

    /**
     * Save debug information
     */
    async saveDebugInfo(debugInfo) {
        const data = {
            userAgent: navigator.userAgent,
            timestamp: Date.now(),
            url: window.location.href,
            ...debugInfo
        };

        return await this.save(this.keys.debug, data);
    }

    /**
     * Get debug information
     */
    async getDebugInfo() {
        return await this.load(this.keys.debug);
    }

    /**
     * Get storage usage statistics
     */
    getStorageStats() {
        if (!this.isAvailable) {
            return { available: false };
        }

        try {
            // Calculate used storage
            let totalSize = 0;
            const itemSizes = {};

            for (let i = 0; i < localStorage.length; i++) {
                const key = localStorage.key(i);
                if (key && key.startsWith(this.prefix)) {
                    const value = localStorage.getItem(key);
                    const size = value ? value.length : 0;
                    totalSize += size;
                    itemSizes[key.replace(this.prefix, '')] = size;
                }
            }

            return {
                available: true,
                totalSize,
                totalSizeFormatted: formatBytes(totalSize),
                itemSizes,
                itemCount: Object.keys(itemSizes).length,
                storageQuotaMB: this.estimateStorageQuota()
            };

        } catch (error) {
            console.error('Failed to calculate storage stats:', error);
            return { available: false, error: error.message };
        }
    }

    /**
     * Estimate storage quota (very rough estimate)
     */
    estimateStorageQuota() {
        // Most browsers have 5-10MB localStorage quota
        return 5; // MB
    }

    /**
     * Cleanup old or unnecessary data
     */
    async cleanup() {
        if (!this.isAvailable) return;

        console.log('Cleaning up storage...');

        try {
            const keysToRemove = [];
            const cutoffTime = Date.now() - (7 * 24 * 60 * 60 * 1000); // 7 days ago

            // Find keys to remove
            for (let i = 0; i < localStorage.length; i++) {
                const key = localStorage.key(i);
                if (key && key.startsWith(this.prefix)) {
                    try {
                        const value = localStorage.getItem(key);
                        const parsed = JSON.parse(value);

                        // Remove old data
                        if (parsed.timestamp && parsed.timestamp < cutoffTime) {
                            keysToRemove.push(key);
                        }

                    } catch (parseError) {
                        // Remove corrupted data
                        keysToRemove.push(key);
                    }
                }
            }

            // Remove identified keys
            keysToRemove.forEach(key => {
                localStorage.removeItem(key);
                console.log(` Cleaned up: ${key}`);
            });

            console.log(` Cleanup complete. Removed ${keysToRemove.length} items.`);

        } catch (error) {
            console.error('Cleanup failed:', error);
        }
    }

    /**
     * Clear all application data
     */
    async clearAll() {
        if (!this.isAvailable) return false;

        console.log('Clearing all storage data...');

        try {
            const keysToRemove = [];

            // Find all our keys
            for (let i = 0; i < localStorage.length; i++) {
                const key = localStorage.key(i);
                if (key && key.startsWith(this.prefix)) {
                    keysToRemove.push(key);
                }
            }

            // Remove all keys
            keysToRemove.forEach(key => {
                localStorage.removeItem(key);
            });

            console.log(` Cleared ${keysToRemove.length} items from storage`);
            return true;

        } catch (error) {
            console.error('Failed to clear storage:', error);
            return false;
        }
    }

    /**
     * Export all data for backup
     */
    async exportData() {
        if (!this.isAvailable) return null;

        try {
            const exportData = {
                timestamp: Date.now(),
                version: '1.0',
                data: {}
            };

            // Export all our data
            for (let i = 0; i < localStorage.length; i++) {
                const key = localStorage.key(i);
                if (key && key.startsWith(this.prefix)) {
                    const shortKey = key.replace(this.prefix, '');
                    const value = localStorage.getItem(key);
                    exportData.data[shortKey] = JSON.parse(value);
                }
            }

            console.log('Exported storage data');
            return exportData;

        } catch (error) {
            console.error('Failed to export data:', error);
            return null;
        }
    }

    /**
     * Import data from backup
     */
    async importData(importData) {
        if (!this.isAvailable) return false;

        try {
            if (!importData.data || typeof importData.data !== 'object') {
                throw new Error('Invalid import data format');
            }

            // Import each item
            for (const [key, value] of Object.entries(importData.data)) {
                const fullKey = this.getKey(key);
                localStorage.setItem(fullKey, JSON.stringify(value));
            }

            console.log(` Imported ${Object.keys(importData.data).length} items`);
            return true;

        } catch (error) {
            console.error('Failed to import data:', error);
            return false;
        }
    }

    /**
     * Cleanup on destroy
     */
    destroy() {
        console.log('Storage Manager cleanup...');
        // Perform any necessary cleanup
        // For now, just run a cleanup to free up space
        this.cleanup();
        console.log('Storage Manager cleanup complete');
    }
}