import assert from 'node:assert/strict'
import { readFile, readdir } from 'node:fs/promises'
import path from 'node:path'

const root = new URL('../', import.meta.url)
const read = p => readFile(new URL(p, root), 'utf8')

const locales = {}
for (const loc of ['cn', 'en', 'hk']) {
  locales[loc] = JSON.parse(await read(`src/views/lang/${loc}.json`))
}

// 扫描源码中真正引用到的 ssArticle* 键，而不是维护一张会过期的手写清单
const scanRoots = [
  'src/views/Editor/EnglishSpeaking',
  'src/views/Student/components/ArticleReadingClassPanel',
  'src/views/components/element/FrameElement',
  'src/views/Editor/CanvasTool',
  'src/components/CollapsibleToolbar',
  'src/views/Student',
]

async function collectFiles(dir) {
  const out = []
  let entries
  try {
    entries = await readdir(new URL(dir + '/', root), { withFileTypes: true })
  } catch {
    return out
  }
  for (const entry of entries) {
    const child = path.posix.join(dir, entry.name)
    if (entry.isDirectory()) out.push(...await collectFiles(child))
    else if (/\.(vue|ts)$/.test(entry.name)) out.push(child)
  }
  return out
}

const files = (await Promise.all(scanRoots.map(collectFiles))).flat()
const used = new Set()
for (const file of files) {
  const source = await read(file)
  for (const match of source.matchAll(/\blang\.(ssArticle[A-Za-z0-9]*)/g)) used.add(match[1])
}

assert.ok(used.size > 20, `expected many article keys in use, found ${used.size}`)

// 每个被引用的键在三个语言包里都必须存在、非空、无首尾空白
const missing = []
for (const key of [...used].sort()) {
  for (const loc of ['cn', 'en', 'hk']) {
    const value = locales[loc][key]
    if (typeof value !== 'string' || value.length === 0) {
      missing.push(`${loc}.json missing ${key}`)
      continue
    }
    assert.equal(value, value.trim(), `${loc}.json ${key} has surrounding whitespace`)
  }
}
assert.deepEqual(missing, [], `unresolved article i18n keys:\n${missing.join('\n')}`)

// 三个语言包的 ssArticle* 键集合必须完全一致，防止某个语言漏翻
const keySets = Object.fromEntries(
  Object.entries(locales).map(([loc, pack]) => [
    loc,
    Object.keys(pack).filter(key => key.startsWith('ssArticle')).sort(),
  ]),
)
assert.deepEqual(keySets.en, keySets.cn, 'en.json article keys differ from cn.json')
assert.deepEqual(keySets.hk, keySets.cn, 'hk.json article keys differ from cn.json')

// en 与 cn 的文案不应逐字相同（除少数本就一致的符号型文案）
const identical = keySets.cn.filter(key => locales.en[key] === locales.cn[key])
assert.ok(
  identical.length <= 2,
  `en.json looks untranslated for: ${identical.join(', ')}`,
)

console.log(`article reading i18n: ${used.size} keys used, ${keySets.cn.length} defined, all three locales consistent`)
