import 'dayjs/locale/zh-cn';
import 'dayjs/locale/en';

import type { Locale as AntdLocale } from 'ant-design-vue/es/locale';
import enUS from 'ant-design-vue/es/locale/en_US';
import zhCN from 'ant-design-vue/es/locale/zh_CN';
import dayjs from 'dayjs';
import { invert, mapKeys, mapValues } from 'lodash-es';
import { ref, watch } from 'vue';
import { createI18n } from 'vue-i18n';

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

enum Locale {
  简体中文 = 'zh-CN',
  English = 'en-US',
}
export const LOCALES = Object.freeze<[string, Locale][]>(Object.entries(Locale));

export const i18n = createI18n({
  legacy: false,
  missingWarn: false,
  fallbackWarn: false,
  locale: Locale.简体中文,
  messages: mapValues(invert(Locale), (_, k) => LOCAL_MAP[k] ?? {}),
});

const LOCALE_STORAGE_KEY = 'locale';

class LocaleService {
  #locale = ref<Locale>(<Locale>localStorage.getItem(LOCALE_STORAGE_KEY) || Locale.简体中文);
  public get locale(): Locale {
    return this.#locale.value;
  }
  public set locale(v: Locale) {
    this.#locale.value = v;
    localStorage.setItem(LOCALE_STORAGE_KEY, v);
  }

  public get ant(): AntdLocale {
    switch (this.#locale.value) {
      case Locale.English:
        return enUS;
      case Locale.简体中文:
      default:
        return zhCN;
    }
  }

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

  #load(locale: Locale): void {
    i18n.global.locale.value = locale;
    switch (locale) {
      case Locale.English:
        dayjs.locale('en');
        break;
      case Locale.简体中文:
      default:
        dayjs.locale('zh-cn');
        break;
    }
  }
}
export default new LocaleService();
