/**
 * @moduleName: SettingsManager Service
 * @version: 1.0.0
 * @since: 2025-07-28
 * @lastUpdated: 2025-07-28
 * @requirementsTraceability: [Add relevant requirements]
 * @briefDescription: [Add description of functionality]
 * @contributors: Claude Code Agent
 */

import {
    AccessibilitySettings,
    AppSettings,
    PerformanceSettings,
    QuizSettings,
    UISettings,
} from '../types/index';

/**
 * Singleton service for managing application settings
 * Handles persistence, validation, and change notifications
 */
export class SettingsManager {
  private static instance: SettingsManager;
  private settings: AppSettings;
  private changeListeners: ((settings: AppSettings) => void)[] = [];
  private readonly STORAGE_KEY = 'quiz-platform-settings';

  private constructor() {
    this.settings = this.getDefaultSettings();
    this.loadSettings();
  }

  /**
   * Get singleton instance
   */
  static getInstance(): SettingsManager {
    if (!SettingsManager.instance) {
      SettingsManager.instance = new SettingsManager();
    }
    return SettingsManager.instance;
  }

  /**
   * Get default settings configuration
   */
  private getDefaultSettings(): AppSettings {
    return {
      ui: {
        theme: 'system',
        fontSize: 'medium',
        navigationVisible: true,
        reducedMotion: false,
        animations: true,
        celebration: true,
        announceChanges: false,
      },
      quiz: {
        viewMode: 'single',
        autoAdvance: {
          enabled: false,
          delaySeconds: 3,
          showCountdown: true,
        },
        showProgress: true,
        largeButtons: false,
        preloadQuestions: true,
        minimalUI: false,
      },
      accessibility: {
        screenReaderMode: false,
        keyboardNavigation: true,
        skipLinks: false,
        highContrast: false,
      },
      performance: {
        lazyLoading: true,
        compactMode: false,
        disableAnalytics: false,
        cacheOptimized: true,
      },
    };
  }

  /**
   * Load settings from localStorage
   */
  private loadSettings(): void {
    try {
      const stored = localStorage.getItem(this.STORAGE_KEY);
      if (stored) {
        const parsedSettings = JSON.parse(stored);
        this.settings = this.mergeWithDefaults(parsedSettings);
        console.log('⚙️ Settings loaded from localStorage:', this.settings);
      }
    } catch (error) {
      console.warn('Failed to load settings from localStorage:', error);
      this.settings = this.getDefaultSettings();
    }
  }

  /**
   * Merge stored settings with defaults to handle new settings
   */
  private mergeWithDefaults(stored: Partial<AppSettings>): AppSettings {
    const defaults = this.getDefaultSettings();

    return {
      ui: { ...defaults.ui, ...stored.ui },
      quiz: {
        ...defaults.quiz,
        ...stored.quiz,
        autoAdvance: { ...defaults.quiz.autoAdvance, ...stored.quiz?.autoAdvance },
      },
      accessibility: { ...defaults.accessibility, ...stored.accessibility },
      performance: { ...defaults.performance, ...stored.performance },
    };
  }

  /**
   * Save settings to localStorage
   */
  private saveSettings(): void {
    try {
      localStorage.setItem(this.STORAGE_KEY, JSON.stringify(this.settings));
      console.log('💾 Settings saved to localStorage');
    } catch (error) {
      console.error('Failed to save settings to localStorage:', error);
    }
  }

  /**
   * Get current settings
   */
  getSettings(): AppSettings {
    return { ...this.settings };
  }

  /**
   * Get specific setting value using dot notation
   */
  getSetting<T>(path: string): T | undefined {
    return this.getNestedValue(this.settings, path);
  }

  /**
   * Update a specific setting
   */
  updateSetting(path: string, value: any): void {
    const oldSettings = { ...this.settings };
    this.setNestedValue(this.settings, path, value);

    this.saveSettings();
    this.notifyChangeListeners();

    console.log(`⚙️ Setting updated: ${path} =`, value);
  }

  /**
   * Apply bulk settings (used for demo configurations)
   */
  applyBulkSettings(newSettings: Partial<AppSettings>): void {
    const oldSettings = { ...this.settings };
    this.settings = this.mergeWithDefaults(newSettings);

    this.saveSettings();
    this.notifyChangeListeners();

    console.log('⚙️ Bulk settings applied:', newSettings);
  }

  /**
   * Reset settings to defaults
   */
  resetToDefaults(): void {
    this.settings = this.getDefaultSettings();
    this.saveSettings();
    this.notifyChangeListeners();

    console.log('🔄 Settings reset to defaults');
  }

  /**
   * Subscribe to settings changes
   */
  subscribe(listener: (settings: AppSettings) => void): () => void {
    this.changeListeners.push(listener);

    // Return unsubscribe function
    return () => {
      const index = this.changeListeners.indexOf(listener);
      if (index > -1) {
        this.changeListeners.splice(index, 1);
      }
    };
  }

  /**
   * Notify all change listeners
   */
  private notifyChangeListeners(): void {
    this.changeListeners.forEach(listener => {
      try {
        listener(this.getSettings());
      } catch (error) {
        console.error('Error in settings change listener:', error);
      }
    });
  }

  /**
   * Export settings for sharing/backup
   */
  exportSettings(): string {
    return JSON.stringify(this.settings, null, 2);
  }

  /**
   * Import settings from JSON string
   */
  importSettings(jsonString: string): boolean {
    try {
      const importedSettings = JSON.parse(jsonString);
      this.applyBulkSettings(importedSettings);
      return true;
    } catch (error) {
      console.error('Failed to import settings:', error);
      return false;
    }
  }

  /**
   * Validate settings structure
   */
  validateSettings(settings: any): boolean {
    try {
      // Basic structure validation
      return (
        typeof settings === 'object' &&
        settings.ui &&
        typeof settings.ui === 'object' &&
        settings.quiz &&
        typeof settings.quiz === 'object' &&
        settings.accessibility &&
        typeof settings.accessibility === 'object' &&
        settings.performance &&
        typeof settings.performance === 'object'
      );
    } catch {
      return false;
    }
  }

  /**
   * Get nested object value using dot notation
   */
  private getNestedValue(obj: any, path: string): any {
    return path.split('.').reduce((current, key) => current?.[key], obj);
  }

  /**
   * Set nested object value using dot notation
   */
  private setNestedValue(obj: any, path: string, value: any): void {
    const keys = path.split('.');
    const lastKey = keys.pop()!;
    const target = keys.reduce((current, key) => {
      if (!current[key] || typeof current[key] !== 'object') {
        current[key] = {};
      }
      return current[key];
    }, obj);

    target[lastKey] = value;
  }

  /**
   * Get settings for a specific category
   */
  getUISettings(): UISettings {
    return { ...this.settings.ui };
  }

  getQuizSettings(): QuizSettings {
    return { ...this.settings.quiz };
  }

  getAccessibilitySettings(): AccessibilitySettings {
    return { ...this.settings.accessibility };
  }

  getPerformanceSettings(): PerformanceSettings {
    return { ...this.settings.performance };
  }

  /**
   * Apply accessibility-optimized settings
   */
  applyAccessibilityMode(): void {
    this.applyBulkSettings({
      ui: {
        theme: 'high-contrast',
        fontSize: 'large',
        navigationVisible: true,
        reducedMotion: true,
        animations: false,
        celebration: false,
        announceChanges: true,
      },
      accessibility: {
        screenReaderMode: true,
        keyboardNavigation: true,
        skipLinks: true,
        highContrast: true,
      },
      quiz: {
        viewMode: 'single',
        autoAdvance: {
          enabled: false,
          delaySeconds: 5,
          showCountdown: true,
        },
        showProgress: true,
        largeButtons: true,
        preloadQuestions: true,
        minimalUI: false,
      },
    });
  }

  /**
   * Apply performance-optimized settings
   */
  applyPerformanceMode(): void {
    this.applyBulkSettings({
      ui: {
        theme: 'light',
        fontSize: 'medium',
        navigationVisible: false,
        reducedMotion: true,
        animations: false,
        celebration: false,
        announceChanges: false,
      },
      quiz: {
        viewMode: 'single',
        autoAdvance: {
          enabled: true,
          delaySeconds: 1,
          showCountdown: false,
        },
        showProgress: false,
        largeButtons: false,
        preloadQuestions: false,
        minimalUI: true,
      },
      performance: {
        lazyLoading: true,
        compactMode: true,
        disableAnalytics: true,
        cacheOptimized: true,
      },
    });
  }
}
