import { ref } from 'vue'
import zhUI from '@/locales/zh.json'
import enUI from '@/locales/en.json'
import jaUI from '@/locales/ja.json'

const uiMessages = { zh: zhUI, en: enUI, ja: jaUI } as const
type Lang = string

const currentLang = ref<Lang>(localStorage.getItem('lang') || 'zh')
const storyMessages = ref<Record<string, Record<string, any>>>({})
const storyLoading = new Set<string>()
let localesPath = ''

function resolveLocalePath(lang: string): string {
  const base = localesPath.endsWith('/') ? localesPath : localesPath + '/'
  return base + lang + '.json'
}

export async function initStoryLocales(path: string, lang?: string) {
  localesPath = path
  return loadStoryMessages(lang || currentLang.value)
}

async function loadStoryMessages(lang: string) {
  if (!localesPath || storyMessages.value[lang] || storyLoading.has(lang)) return
  storyLoading.add(lang)
  try {
    const resp = await fetch(resolveLocalePath(lang))
    if (resp.ok) {
      storyMessages.value = {
        ...storyMessages.value,
        [lang]: await resp.json(),
      }
    }
  } catch {
    /* story locales optional */
  } finally {
    storyLoading.delete(lang)
  }
}

function t(key: string): string {
  const parts = key.split('.')

  let result: any = storyMessages.value[currentLang.value]
  for (const p of parts) {
    result = result?.[p]
  }
  if (typeof result === 'string') return result

  const uiLang = currentLang.value as keyof typeof uiMessages
  let fallback: any = (uiMessages as any)[uiLang] || uiMessages.zh
  for (const p of parts) {
    fallback = fallback?.[p]
  }
  if (typeof fallback === 'string') return fallback

  return key
}

async function setLang(lang: string) {
  await loadStoryMessages(lang)
  currentLang.value = lang
  localStorage.setItem('lang', lang)
}

export function useI18n() {
  return { t, currentLang, setLang }
}
