/**
 * End-to-end check of the generated catalogs.
 *
 * Loads each `languages/frontend/<locale>.php` through PHP itself (so the real
 * artifact is tested, not a re-parse of it), feeds it to the same
 * `@wordpress/i18n` runtime the SPA bundles, and asserts that translation,
 * plural selection, and positional placeholders all resolve.
 *
 *   node tools/i18n-verify.mjs
 */
import { execFileSync } from 'node:child_process'
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { __, _n, setLocaleData, sprintf } from '@wordpress/i18n'

const ROOT = path.resolve(import.meta.dirname, '..')
const DOMAIN = 'easylink-automations'

/** Read a generated locale-data file by executing it in PHP. */
function loadLocaleData(locale) {
  const file = path.join(ROOT, 'languages', 'frontend', `${locale}.php`)
  const json = execFileSync(
    'php',
    ['-r', `define('ABSPATH', 1); echo json_encode(include ${JSON.stringify(file)});`],
    { encoding: 'utf8' }
  )
  return JSON.parse(json)
}

/**
 * Spot-checks per locale. These are deliberately a handful of strings that
 * appear on the busiest screens — enough to prove the wiring, not a re-review
 * of the translations themselves.
 */
const EXPECTED = {
  es_ES: { 'Save Settings': 'Guardar ajustes', Delete: 'Eliminar', Status: 'Estado' },
  fr_FR: { 'Save Settings': 'Enregistrer les réglages', Delete: 'Supprimer', Status: 'État' },
  de_DE: { 'Save Settings': 'Einstellungen speichern', Delete: 'Löschen', Status: 'Status' },
  pt_BR: { 'Save Settings': 'Salvar configurações', Delete: 'Excluir', Status: 'Status' },
  it_IT: { 'Save Settings': 'Salva impostazioni', Delete: 'Elimina', Status: 'Stato' },
  nl_NL: { 'Save Settings': 'Instellingen opslaan', Delete: 'Verwijderen', Status: 'Status' },
  ja: { 'Save Settings': '設定を保存', Delete: '削除', Status: 'ステータス' },
  ru_RU: { 'Save Settings': 'Сохранить настройки', Delete: 'Удалить', Status: 'Статус' },
  hi_IN: { 'Save Settings': 'सेटिंग्स सहेजें', Delete: 'हटाएँ', Status: 'स्थिति' },
  bn_BD: { 'Save Settings': 'সেটিংস সংরক্ষণ', Delete: 'মুছুন', Status: 'অবস্থা' },
}

/** Plural rules differ per locale; these are the forms each should pick. */
const PLURAL_CASES = {
  ru_RU: { 1: '%d действие', 3: '%d действия', 7: '%d действий' },
  ja: { 1: '%d 件のアクション', 5: '%d 件のアクション' },
  fr_FR: { 1: '%d action', 5: '%d actions' },
}

let failures = 0

const check = (label, actual, expected) => {
  if (actual === expected) return
  failures += 1
  console.error(`  FAIL ${label}\n         got: ${actual}\n    expected: ${expected}`)
}

console.log('locale data')

for (const [locale, strings] of Object.entries(EXPECTED)) {
  const file = path.join(ROOT, 'languages', 'frontend', `${locale}.php`)

  if (!fs.existsSync(file)) {
    failures += 1
    console.error(`  FAIL ${locale}: ${path.relative(ROOT, file)} is missing`)
    continue
  }

  const data = loadLocaleData(locale)
  setLocaleData(data, DOMAIN)

  for (const [source, expected] of Object.entries(strings)) {
    check(`${locale} __("${source}")`, __(source, DOMAIN), expected)
  }

  const count = Object.keys(data).length - 1
  console.log(`  ${locale}: ${count} strings, header lang=${data['']?.lang}`)
}

console.log('\nplural selection')

for (const [locale, cases] of Object.entries(PLURAL_CASES)) {
  setLocaleData(loadLocaleData(locale), DOMAIN)

  for (const [n, expected] of Object.entries(cases)) {
    const got = _n('%d action', '%d actions', Number(n), DOMAIN)
    check(`${locale} _n(n=${n})`, got, expected)
    console.log(`  ${locale} n=${n}: ${sprintf(got, Number(n))}`)
  }
}

console.log('\npositional placeholders')

setLocaleData(loadLocaleData('de_DE'), DOMAIN)
const versionLine = sprintf(__('%1$s version %2$s', DOMAIN), 'EasyLink Automations', '1.1.6')
check('de_DE %1$s/%2$s ordering', versionLine, 'EasyLink Automations Version 1.1.6')
console.log(`  de_DE: ${versionLine}`)

setLocaleData(loadLocaleData('ja'), DOMAIN)
const oauthLine = sprintf(
  __('Copy this URL and paste it as the %1$s (or %2$s) in your %3$s OAuth app settings.', DOMAIN),
  'Redirect URI',
  'Callback URL',
  'Slack'
)
check(
  'ja reordered placeholders',
  oauthLine,
  'この URL をコピーし、Slack の OAuth アプリ設定の Redirect URI (または Callback URL) に貼り付けてください。'
)
console.log(`  ja:    ${oauthLine}`)

console.log(failures === 0 ? '\nall checks passed' : `\n${failures} check(s) failed`)
process.exit(failures ? 1 : 0)
