/**
 * @moduleName: Theme Management Service - UI Theme & Dark Mode System
 * @version: 2.0.0
 * @since: 2025-07-21
 * @lastUpdated: 2025-07-27
 * @projectSummary: Enhanced MCP Quiz Server - Theme management with light/dark/system modes and smooth transitions
 * @techStack: TypeScript, Singleton Pattern, LocalStorage, CSS Classes, Media Queries
 * @dependency: ThemeConfig, ThemeMode, ThemeColor interfaces from types/index.js
 * @interModuleDependency: DOM manipulation, localStorage persistence, CSS theme variables
 * @requirementsTraceability:
 *   {@link Requirements.REQ_CONFIG_003} (Theme System Management)
 *   {@link Requirements.REQ_UI_003} (Advanced Settings)
 * @briefDescription: Singleton service managing theme preferences with system detection, persistence, and smooth transitions
 * @methods: setMode, setColor, toggleDarkMode, applyTheme, subscribe, initialize
 * @contributors: GitHub Copilot, Frontend Team
 * @examples:
 *   - ThemeService.getInstance().setMode('dark')
 *   - ThemeService.getInstance().toggleDarkMode()
 *   - const unsubscribe = themeService.subscribe(theme => console.log(theme))
 * @vulnerabilitiesAssessment: LocalStorage XSS prevention via JSON parsing, CSS injection prevention through class allowlist
 */

import { ThemeColor, ThemeConfig, ThemeMode } from '../types/index';

export class ThemeService {
  private static instance: ThemeService;
  private currentTheme: ThemeConfig;
  private listeners: Set<(theme: ThemeConfig) => void> = new Set();

  private constructor() {
    this.currentTheme = this.loadThemeFromStorage();
    this.initializeSystemThemeListener();
  }

  static getInstance(): ThemeService {
    if (!ThemeService.instance) {
      ThemeService.instance = new ThemeService();
    }
    return ThemeService.instance;
  }

  private loadThemeFromStorage(): ThemeConfig {
    const saved = localStorage.getItem('quiz-theme');
    if (saved) {
      try {
        const parsed = JSON.parse(saved);
        // Ensure only mode is used for simplified theme system
        return { mode: parsed.mode || 'system', color: 'slate' };
      } catch (e) {
        console.warn('Invalid theme data in localStorage');
      }
    }
    return { mode: 'system', color: 'slate' };
  }

  private saveThemeToStorage(): void {
    localStorage.setItem('quiz-theme', JSON.stringify(this.currentTheme));
  }

  private initializeSystemThemeListener(): void {
    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
      if (this.currentTheme.mode === 'system') {
        this.applyTheme();
      }
    });
  }

  getTheme(): ThemeConfig {
    return { ...this.currentTheme };
  }

  setMode(mode: ThemeMode): void {
    this.currentTheme.mode = mode;
    this.applyTheme();
    this.saveThemeToStorage();
    this.notifyListeners();
  }

  setColor(color: ThemeColor): void {
    this.currentTheme.color = color;
    this.applyTheme();
    this.saveThemeToStorage();
    this.notifyListeners();
  }

  toggleDarkMode(): void {
    const newMode = this.currentTheme.mode === 'dark' ? 'light' : 'dark';
    this.setMode(newMode);
  }

  applyTheme(): void {
    const html = document.documentElement;

    // Remove existing theme classes (simplified - only dark mode)
    html.classList.remove('dark');

    // Apply dark/light mode based on setting
    if (this.currentTheme.mode === 'dark') {
      html.classList.add('dark');
    } else if (this.currentTheme.mode === 'system') {
      const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
      if (prefersDark) {
        html.classList.add('dark');
      }
    }
    // Light mode: no class needed (default)

    // Trigger smooth transition
    document.body.classList.add('theme-transition');
    setTimeout(() => {
      document.body.classList.remove('theme-transition');
    }, 300);
  }

  subscribe(callback: (theme: ThemeConfig) => void): () => void {
    this.listeners.add(callback);
    return () => {
      this.listeners.delete(callback);
    };
  }

  private notifyListeners(): void {
    this.listeners.forEach(callback => callback(this.getTheme()));
  }

  initialize(): void {
    this.applyTheme();
  }
}
