// 用語のブレを直す。--apply を付けると overrides.json に書き込む。
//
// 訳文だけを見て置換すると巻き添えが出る（"lace by the yard" の「ヤード」は
// 正しいし、"in your chest" の「胸」も正しい）。だから
//   ・原文がゲーム内の意味で使っているか（英語側の条件）
//   ・訳文に誤読が出ているか（日本語側の条件）
// の両方が揃ったものだけを直す。
import fs from 'fs';

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 RULES = [
  {
    note: 'Roll = 名誉録（サイコロを振る、ではない）',
    when: en => /\bRoll\b/.test(en) && !/\broll(s|ed|ing)?\b\s*(a|the|\d|d20)/i.test(en),
    // 「振るう」は別語なので触らない。助詞か句読点が続くものだけ。
    fix: ja => ja.replace(/振る(?=[のはをにがでとも、。」）]|$)/g, '名誉録'),
  },
  {
    note: 'rank cap = 階級上限（cap は帽子ではない）',
    when: en => /rank[- ]cap/i.test(en),
    fix: ja => ja.replace(/階級帽/g, '階級上限').replace(/ランクキャップ/g, '階級上限')
                 .replace(/階級の帽子/g, '階級上限'),
  },
  {
    note: 'stand = 段（階級上限の一段）',
    when: en => /\bstand(s|ing)?\b/.test(en) && /hireling|rank|cap|yard/i.test(en),
    fix: ja => ja.replace(/舞台装置/g, '段').replace(/立札/g, '段').replace(/スタンド/g, '段'),
  },
  {
    note: 'stage = 段階',
    when: en => /\bstage(s)?\b/.test(en),
    fix: ja => ja.replace(/舞台装置/g, '段階'),
  },
  {
    note: 'the yard = 需品係の庭',
    when: en => /\byard\b/.test(en) && /hireling|stand|rank|quartermaster|drill/i.test(en)
             && !/by the yard/i.test(en),          // 「ヤード単位で買う」は長さの単位
    fix: ja => ja.replace(/ドリルヤード/g, '訓練場').replace(/ヤード/g, '需品係の庭'),
  },
  {
    note: 'book of hands = 雇い人の書',
    when: en => /book of hands/i.test(en),
    fix: ja => ja.replace(/手の書かれた本/g, '雇い人の書').replace(/手の書/g, '雇い人の書'),
  },
  {
    note: 'mimic = ミミック',
    when: en => /\bmimic(s)?\b/i.test(en),
    fix: ja => ja.replace(/擬態生物/g, 'ミミック').replace(/模倣者/g, 'ミミック')
                 .replace(/模倣する(?=[。、]|$)/g, 'ミミック'),
  },
  {
    note: 'Barracks = 兵舎',
    when: en => /\bBarracks\b/.test(en),
    fix: ja => ja.replace(/バラックス/g, '兵舎'),
  },
  {
    note: 'sending = 送り（送電ではない）',
    when: en => /\bsending\b/.test(en),
    fix: ja => ja.replace(/送電/g, '送り'),
  },
  {
    note: 'chest = 櫃（宝箱。胸ではない）',
    when: en => /\b(a|the) chest\b/i.test(en) && !/your chest|his chest|her chest|its chest|in the chest/i.test(en),
    fix: ja => ja.replace(/胸板/g, '櫃').replace(/胸の箱/g, '櫃'),
  },
  {
    note: 'skill tree の quarter = 象限',
    when: en => /\bquarter\b/.test(en) && /skill|chart|ring|clause|Mending|Finding|Warding|oath/i.test(en)
             && !/quarter-rent|quarter of the year/i.test(en),
    fix: ja => ja.replace(/四半期/g, '象限'),
  },
];

const live = s => src.includes(s);
const props = [];
for (const en in tm) {
  if (ov[en] !== undefined) continue;
  const ja0 = String(tm[en]);
  if (!/[ぁ-んァ-ヴ一-龯]/.test(ja0)) continue;
  if (!live(en)) continue;
  let ja = ja0, notes = [];
  for (const r of RULES) {
    if (!r.when(en)) continue;
    const next = r.fix(ja);
    if (next !== ja) { ja = next; notes.push(r.note); }
  }
  if (ja !== ja0) props.push({ en, before: ja0, after: ja, notes });
}

console.log(`直す提案: ${props.length} 件\n`);
const byNote = {};
for (const p of props) for (const n of p.notes) byNote[n] = (byNote[n] || 0) + 1;
Object.entries(byNote).sort((a, b) => b[1] - a[1]).forEach(([k, v]) => console.log(`  ${String(v).padStart(3)}件  ${k}`));
console.log();

for (const p of props.slice(0, Number(process.env.SHOW || 25))) {
  // 変わった箇所の前後だけ出す
  let i = 0;
  while (i < p.before.length && p.before[i] === p.after[i]) i++;
  const a = Math.max(0, i - 26);
  console.log(`[${p.notes.join(' / ')}]`);
  console.log(`  旧 …${p.before.slice(a, i + 34)}…`);
  console.log(`  新 …${p.after.slice(a, i + 34)}…`);
}

if (process.argv.includes('--apply')) {
  for (const p of props) ov[p.en] = p.after;
  fs.writeFileSync('overrides.json', JSON.stringify(ov, null, 1));
  console.log(`\noverrides.json に ${props.length} 件を書き込みました。`);
} else {
  console.log('\n（--apply を付けると overrides.json に書き込みます）');
}
