/**
 * ==========================================================================
 * THEME STORAGE SERVICE
 * ==========================================================================
 * Handles persistence of themes and user preferences using localStorage
 * Provides backup and import/export functionality
 * ==========================================================================
 */

import { ThemeConfig, ThemeCollection } from '../models/hcl.models';

export class ThemeStorage {

  private static readonly STORAGE_KEYS = {
    CURRENT_THEME: 'hcl-studio-current-theme',
    CURRENT_MODE: 'hcl-studio-current-mode',
    CUSTOM_THEMES: 'hcl-studio-custom-themes',
    USER_PREFERENCES: 'hcl-studio-preferences'
  } as const;

  // ==========================================================================
  // CURRENT THEME PERSISTENCE
  // ==========================================================================

  /**
   * Save current theme ID
   * @param themeId Theme identifier
   */
  static saveCurrentTheme(themeId: string): void {
    try {
      localStorage.setItem(this.STORAGE_KEYS.CURRENT_THEME, themeId);
    } catch (error) {
      console.warn('Failed to save current theme:', error);
    }
  }

  /**
   * Get current theme ID
   * @returns Current theme ID or null
   */
  static getCurrentTheme(): string | null {
    try {
      return localStorage.getItem(this.STORAGE_KEYS.CURRENT_THEME);
    } catch (error) {
      console.warn('Failed to get current theme:', error);
      return null;
    }
  }

  /**
   * Save current mode (light/dark)
   * @param mode Current mode
   */
  static saveCurrentMode(mode: 'light' | 'dark'): void {
    try {
      localStorage.setItem(this.STORAGE_KEYS.CURRENT_MODE, mode);
    } catch (error) {
      console.warn('Failed to save current mode:', error);
    }
  }

  /**
   * Get current mode
   * @returns Current mode or 'light' as default
   */
  static getCurrentMode(): 'light' | 'dark' {
    try {
      const mode = localStorage.getItem(this.STORAGE_KEYS.CURRENT_MODE);
      return mode === 'dark' ? 'dark' : 'light';
    } catch (error) {
      console.warn('Failed to get current mode:', error);
      return 'light';
    }
  }

  // ==========================================================================
  // CUSTOM THEMES MANAGEMENT
  // ==========================================================================

  /**
   * Save a custom theme
   * @param themeConfig Theme configuration
   */
  static saveCustomTheme(themeConfig: ThemeConfig): void {
    try {
      const customThemes = this.getCustomThemes();
      customThemes[themeConfig.id] = {
        ...themeConfig,
        createdAt: themeConfig.createdAt || new Date()
      };
      
      localStorage.setItem(this.STORAGE_KEYS.CUSTOM_THEMES, JSON.stringify(customThemes));
    } catch (error) {
      console.warn('Failed to save custom theme:', error);
    }
  }

  /**
   * Get all custom themes
   * @returns Custom themes collection
   */
  static getCustomThemes(): { [id: string]: ThemeConfig } {
    try {
      const stored = localStorage.getItem(this.STORAGE_KEYS.CUSTOM_THEMES);
      return stored ? JSON.parse(stored) : {};
    } catch (error) {
      console.warn('Failed to get custom themes:', error);
      return {};
    }
  }

  /**
   * Get specific custom theme
   * @param themeId Theme ID
   * @returns Theme configuration or null
   */
  static getCustomTheme(themeId: string): ThemeConfig | null {
    const customThemes = this.getCustomThemes();
    return customThemes[themeId] || null;
  }

  /**
   * Delete custom theme
   * @param themeId Theme ID to delete
   */
  static deleteCustomTheme(themeId: string): void {
    try {
      const customThemes = this.getCustomThemes();
      delete customThemes[themeId];
      localStorage.setItem(this.STORAGE_KEYS.CUSTOM_THEMES, JSON.stringify(customThemes));
    } catch (error) {
      console.warn('Failed to delete custom theme:', error);
    }
  }

  /**
   * Check if theme is custom (user-created)
   * @param themeId Theme ID
   * @returns True if theme is custom
   */
  static isCustomTheme(themeId: string): boolean {
    const customThemes = this.getCustomThemes();
    return themeId in customThemes;
  }

  // ==========================================================================
  // USER PREFERENCES
  // ==========================================================================

  /**
   * Save user preferences
   * @param preferences User preference object
   */
  static savePreferences(preferences: any): void {
    try {
      localStorage.setItem(this.STORAGE_KEYS.USER_PREFERENCES, JSON.stringify(preferences));
    } catch (error) {
      console.warn('Failed to save preferences:', error);
    }
  }

  /**
   * Get user preferences
   * @returns User preferences or default object
   */
  static getPreferences(): any {
    try {
      const stored = localStorage.getItem(this.STORAGE_KEYS.USER_PREFERENCES);
      return stored ? JSON.parse(stored) : {
        autoMode: false,
        transitionDuration: 300,
        enableSystemTheme: true
      };
    } catch (error) {
      console.warn('Failed to get preferences:', error);
      return {
        autoMode: false,
        transitionDuration: 300,
        enableSystemTheme: true
      };
    }
  }

  // ==========================================================================
  // IMPORT/EXPORT FUNCTIONALITY
  // ==========================================================================

  /**
   * Export theme configuration as JSON string
   * @param themeId Theme ID to export
   * @returns JSON string or null if theme not found
   */
  static exportTheme(themeId: string): string | null {
    const customTheme = this.getCustomTheme(themeId);
    if (!customTheme) return null;

    const exportData = {
      version: '1.0',
      exportDate: new Date().toISOString(),
      theme: customTheme
    };

    return JSON.stringify(exportData, null, 2);
  }

  /**
   * Import theme from JSON string
   * @param jsonString JSON theme data
   * @returns Imported theme config or null if invalid
   */
  static importTheme(jsonString: string): ThemeConfig | null {
    try {
      const importData = JSON.parse(jsonString);
      
      // Validate import data structure
      if (!importData.theme || !importData.theme.id || !importData.theme.name || !importData.theme.colors) {
        throw new Error('Invalid theme format');
      }

      const themeConfig: ThemeConfig = {
        ...importData.theme,
        createdAt: new Date(),
        description: importData.theme.description || 'Imported theme'
      };

      // Check for ID conflicts and rename if necessary
      const existingThemes = this.getCustomThemes();
      if (existingThemes[themeConfig.id]) {
        themeConfig.id = this.generateUniqueId(themeConfig.id, existingThemes);
      }

      // Save imported theme
      this.saveCustomTheme(themeConfig);
      
      return themeConfig;
    } catch (error) {
      console.warn('Failed to import theme:', error);
      return null;
    }
  }

  /**
   * Export all custom themes
   * @returns JSON string with all custom themes
   */
  static exportAllThemes(): string {
    const customThemes = this.getCustomThemes();
    
    const exportData = {
      version: '1.0',
      exportDate: new Date().toISOString(),
      themes: customThemes
    };

    return JSON.stringify(exportData, null, 2);
  }

  /**
   * Import multiple themes from JSON string
   * @param jsonString JSON data with multiple themes
   * @returns Array of imported theme IDs
   */
  static importMultipleThemes(jsonString: string): string[] {
    try {
      const importData = JSON.parse(jsonString);
      const importedIds: string[] = [];
      
      if (!importData.themes) {
        throw new Error('Invalid multi-theme format');
      }

      const existingThemes = this.getCustomThemes();

      Object.values(importData.themes).forEach((theme: any) => {
        if (theme.id && theme.name && theme.colors) {
          let themeConfig: ThemeConfig = {
            ...theme,
            createdAt: new Date(),
            description: theme.description || 'Imported theme'
          };

          // Handle ID conflicts
          if (existingThemes[themeConfig.id]) {
            themeConfig.id = this.generateUniqueId(themeConfig.id, existingThemes);
          }

          this.saveCustomTheme(themeConfig);
          importedIds.push(themeConfig.id);
        }
      });

      return importedIds;
    } catch (error) {
      console.warn('Failed to import multiple themes:', error);
      return [];
    }
  }

  // ==========================================================================
  // UTILITY METHODS
  // ==========================================================================

  /**
   * Generate unique theme ID to avoid conflicts
   * @param baseId Base theme ID
   * @param existingThemes Existing themes to check against
   * @returns Unique theme ID
   */
  private static generateUniqueId(baseId: string, existingThemes: { [id: string]: any }): string {
    let counter = 1;
    let newId = `${baseId}-${counter}`;
    
    while (existingThemes[newId]) {
      counter++;
      newId = `${baseId}-${counter}`;
    }
    
    return newId;
  }

  /**
   * Clear all stored data (reset to defaults)
   */
  static clearAllData(): void {
    try {
      Object.values(this.STORAGE_KEYS).forEach(key => {
        localStorage.removeItem(key);
      });
    } catch (error) {
      console.warn('Failed to clear storage data:', error);
    }
  }

  /**
   * Get storage usage information
   * @returns Storage usage stats
   */
  static getStorageInfo(): { customThemes: number; totalSize: number; isAvailable: boolean } {
    try {
      const customThemes = Object.keys(this.getCustomThemes()).length;
      let totalSize = 0;

      Object.values(this.STORAGE_KEYS).forEach(key => {
        const item = localStorage.getItem(key);
        if (item) {
          totalSize += item.length;
        }
      });

      return {
        customThemes,
        totalSize,
        isAvailable: true
      };
    } catch (error) {
      return {
        customThemes: 0,
        totalSize: 0,
        isAvailable: false
      };
    }
  }

  /**
   * Check if localStorage is available
   * @returns True if localStorage is available
   */
  static isStorageAvailable(): boolean {
    try {
      const test = 'hcl-studio-test';
      localStorage.setItem(test, test);
      localStorage.removeItem(test);
      return true;
    } catch {
      return false;
    }
  }

  /**
   * Create backup of all theme data
   * @returns Backup data object
   */
  static createBackup(): any {
    return {
      version: '1.0',
      backupDate: new Date().toISOString(),
      currentTheme: this.getCurrentTheme(),
      currentMode: this.getCurrentMode(),
      customThemes: this.getCustomThemes(),
      preferences: this.getPreferences()
    };
  }

  /**
   * Restore from backup data
   * @param backupData Backup data object
   * @returns True if restore was successful
   */
  static restoreFromBackup(backupData: any): boolean {
    try {
      if (backupData.currentTheme) {
        this.saveCurrentTheme(backupData.currentTheme);
      }
      
      if (backupData.currentMode) {
        this.saveCurrentMode(backupData.currentMode);
      }
      
      if (backupData.customThemes) {
        localStorage.setItem(this.STORAGE_KEYS.CUSTOM_THEMES, JSON.stringify(backupData.customThemes));
      }
      
      if (backupData.preferences) {
        this.savePreferences(backupData.preferences);
      }
      
      return true;
    } catch (error) {
      console.warn('Failed to restore from backup:', error);
      return false;
    }
  }
}