import { theme, type TokenType as AntdTheme } from 'ant-design-vue';
import { mapKeys, mapValues } from 'lodash-es';
import { ref, watch } from 'vue';

const THEME_MAP = (() => {
  let temp = import.meta.glob('asset/themes/*.json', { eager: true, import: 'default' });
  temp = mapKeys(temp, (_, k) => k.match(/^.*[\\|\\/](.+?)\.[^\\.]+$/)?.[1]);
  temp = mapValues(temp, (v) => v);
  return <Record<string, object>>temp;
})();

enum Theme {
  Light = 'light',
  Dark = 'dark',
}
export const THEMES = Object.freeze<[string, Theme][]>(Object.entries(Theme));

const THEME_STORAGE_KEY = '__APP__DARK__MODE__';

class ThemeService {
  #theme = ref<Theme>(<Theme>localStorage.getItem(THEME_STORAGE_KEY) || Theme.Dark);
  public get theme(): Theme {
    return this.#theme.value;
  }
  public set theme(v: Theme) {
    this.#theme.value = v;
    localStorage.setItem(THEME_STORAGE_KEY, v);
  }

  public get ant(): AntdTheme {
    switch (this.#theme.value) {
      case Theme.Dark:
        return { algorithm: theme.darkAlgorithm };
      case Theme.Light:
        return { algorithm: theme.defaultAlgorithm };
      default:
        return {};
    }
  }

  public get editor(): object {
    return THEME_MAP[`editor-${this.#theme.value}`] ?? {};
  }

  public get empty(): string {
    const { href } = new URL(`../assets/images/empty-${this.#theme.value}.png`, import.meta.url);
    return href;
  }

  constructor() {
    watch(this.#theme, (v) => this.#load(v), { immediate: true });
  }

  #load(theme: Theme): void {
    document.documentElement.setAttribute('theme', theme);
  }
}
export default new ThemeService();
