import {computed, effect, Injectable, signal, WritableSignal} from '@angular/core';
import {Theme} from "../models/theme";

@Injectable({
  providedIn: 'root'
})
export class ThemeSwitchService {
  private readonly THEME_KEY = 'app-theme-mode';

  public theme: WritableSignal<Theme> = signal(Theme.DEFAULT_THEME);
  public darkMode = computed(() => {
    return this.theme().code === 'dark' || (this.theme().code === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
  });

  constructor() {
    effect(() => {
      const currentTheme = this.theme();
      localStorage.setItem(this.THEME_KEY, currentTheme.code);

      const html = document.querySelector('html')!;
      const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

      const isDark = currentTheme.code === 'dark' || (currentTheme.code === 'system' && systemPrefersDark);

      html.classList.toggle('dark', isDark);
    });

    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
      if (this.theme().code === 'system') {
        this.theme.update(t => t);
      }
    });
  }

  initialize() {
    console.info('initializing dark mode service');
    const stored = Theme.THEMES.find(theme => theme.code === localStorage.getItem(this.THEME_KEY));

    if (stored === undefined) {
      this.theme.set(Theme.DEFAULT_THEME);
      return;
    }

    if (stored.code === 'dark' || stored.code === 'light' || stored.code === 'system') {
      this.theme.set(stored);
    } else {
      this.theme.set(Theme.DEFAULT_THEME);
    }
  }

  switchToTheme(theme: Theme) {
    console.info(`switching to theme: ${theme.name}`);
    this.theme.set(theme);
  }

  switchToDark() {
    this.switchToTheme(Theme.THEMES.find(t => t.code === 'dark')!);
  }

  switchToLight() {
    this.switchToTheme(Theme.THEMES.find(t => t.code === 'light')!);
  }
}
