// 画面に残った英語を原因別に仕分ける。
//  A: tm にあるのに反映されていない → 門で弾かれている（理由を出す）
//  B: tm に無い                      → 抽出漏れ
//  C: ソースに丸ごとの形で存在しない → 実行時に組み立てている（語彙表/語順の仕事）
import fs from 'fs';

const hits = JSON.parse(fs.readFileSync('screen-en-all.json', 'utf8'));
const tm = JSON.parse(fs.readFileSync('tm.json', 'utf8'));
const ov = JSON.parse(fs.readFileSync('overrides.json', 'utf8'));
const src = fs.readFileSync('app/game/index.html', 'utf8');

const norm = s => s.replace(/\s+/g, ' ').trim();
const tmKeys = new Map();
for (const k of Object.keys(tm)) tmKeys.set(norm(k), k);
for (const k of Object.keys(ov)) tmKeys.set(norm(k), k);

// ソースに素の文字列として出てくるか（数字を伏せた形でも試す）
const inSource = s => src.includes(s);
const generalized = s => s.replace(/\b\d[\d.,]*\b/g, '');
const srcGen = generalized(src);

const A = [], B = [], C = [], D = [];
const SKIP = /^(https?:|creativecommons|Windows |GNOME |Mac OS |[IVXLC]+$)/;

for (const h of hits) {
  const t = norm(h.t);
  if (SKIP.test(t)) { D.push(h); continue; }
  const key = tmKeys.get(t);
  if (key) { A.push({ ...h, ja: tm[key] || ov[key] }); continue; }
  if (inSource(t)) { B.push(h); continue; }
  if (srcGen.includes(generalized(t))) { C.push({ ...h, note: '数字だけ違う' }); continue; }
  C.push(h);
}

const show = (label, arr, n = 200) => {
  console.log(`\n########## ${label} : ${arr.length} 件 ##########`);
  arr.slice(0, n).forEach(x =>
    console.log(`${String(x.n).padStart(4)}回 [${String(x.where).slice(0, 16).padEnd(16)}] ${x.t.slice(0, 78)}`
      + (x.ja ? `\n            → ${String(x.ja).slice(0, 70)}` : '')
      + (x.note ? `  (${x.note})` : '')));
};

show('A: 訳はあるのに反映されていない', A);
show('B: 訳が無い（抽出漏れ）', B);
show('C: 実行時に組み立てている', C.filter(x => !/^item level \d+$/.test(x.t)), 120);
console.log(`\n  ※ C のうち "item level N" 形が ${C.filter(x => /^item level \d+$/.test(x.t)).length} 件`);
show('D: 訳さないもの', D, 10);

fs.writeFileSync('triage.json', JSON.stringify({ A, B, C, D }, null, 1));
