import { App, WritableComputedRef, ref } from 'vue'
import { createI18n, I18n as BaseI18n } from 'vue-i18n'
import { deflangName, langNameEum, langNames, langNameDescs } from './constant'
import { localGetFactory, localSetFactory } from '@/utils/store'
import { paramsToStr, strToParams } from '@/utils'
import zh, { promise as zhPromise } from './zh'
import en, { promise as enPromise } from './en'
import jp, { promise as jpPromise } from './ja'

type I18n = BaseI18n & {
  global: {
    t: I18nGlobalTranslation
    changeLang(langName: langNameEum, reload?: boolean): void
    locale: WritableComputedRef<langNameEum>
  }
}

export const loaded = ref(false)
Promise.all([zhPromise, enPromise, jpPromise]).then(() => (loaded.value = true))
const localKey = 'lang'
const local = {
  get: localGetFactory(str => {
    if (str) {
      return str as langNameEum
    } else {
      const langs = Object.keys(langNameDescs)
      const defLang = window?.navigator?.language || 'en'

      const navLang = langs.find(lang =>
        new RegExp(`-?${lang}-?`).test(defLang)
      )
      console.log('language:', navLang)
      return navLang || langNameEum.en
    }
  }),
  set: localSetFactory((lang: langNameEum) => lang)
}

const params = strToParams(location.search)
export const lang = (params.lang || local.get(localKey)) as langNameEum
if (lang !== local.get(localKey)) {
  local.set(localKey, lang)
}

const i18n: I18n = createI18n({
  legacy: false,
  fallbackLocale: deflangName,
  availableLocales: langNames,
  locale: lang,
  sync: true,
  silentTranslationWarn: true,
  missingWarn: false,
  silentFallbackWarn: true
}) as I18n

export const langs = {
  [langNameEum.en]: en,
  [langNameEum.zh]: zh,
  [langNameEum.jp]: jp
}

i18n.global.setLocaleMessage(langNameEum.zh, zh)
i18n.global.setLocaleMessage(langNameEum.en, en)
i18n.global.setLocaleMessage(langNameEum.jp, jp)
i18n.global.changeLang = (lang: langNameEum, reload = true) => {
  i18n.global.locale.value = lang
  local.set(localKey, lang)
  params.lang = lang
  if (reload) {
    location.search = paramsToStr(params)
  }
  // location.reload()
}

export const setupI18n = (app: App) => {
  app.config.globalProperties.$t = i18n.global.t
  app.use(i18n)
}
export const changeLang = i18n.global.changeLang
export const ui18n = i18n.global
export const useI18n = () => ui18n

export * from './constant'
