// DeepL がタグを足したり落としたりした訳文を、原文のタグ構成に合わせて直す。
// 直せたものだけ tm.json に書き戻す（直せないものは英語のまま残る）。
import fs from 'fs';

const tm = JSON.parse(fs.readFileSync('tm.json', 'utf8'));
const TAG = /<\/?[a-zA-Z][^>]*>/g;
const list = s => (s.match(TAG) || []).map(t => t.replace(/\s+/g, ' '));
const key = s => list(s).slice().sort().join('|');

const affix = s => {
  const pre = (s.match(/^(?:\s*<\/?[a-zA-Z][^>]*>)+/) || [''])[0];
  let rest = s.slice(pre.length);
  const suf = (rest.match(/(?:<\/?[a-zA-Z][^>]*>\s*)+$/) || [''])[0];
  return { pre, core: rest.slice(0, rest.length - suf.length), suf };
};

// JA から「原文にない余分なタグ」を消す
function dropExtra(en, ja) {
  const want = list(en).slice();
  let out = '';
  let last = 0;
  for (const m of ja.matchAll(TAG)) {
    const t = m[0].replace(/\s+/g, ' ');
    const i = want.indexOf(t);
    out += ja.slice(last, m.index);
    if (i >= 0) { out += m[0]; want.splice(i, 1); }   // 原文にあるタグは残す
    last = m.index + m[0].length;
  }
  return out + ja.slice(last);
}

let fixedAffix = 0, fixedExtra = 0, fixedRebuild = 0, still = 0;
const unfixed = [];
for (const [en, ja] of Object.entries(tm)) {
  if (key(en) === key(ja)) continue;

  // 1) 余分なタグを落とすだけで合うか
  let cand = dropExtra(en, ja);
  if (key(cand) === key(en)) { tm[en] = cand; fixedExtra++; continue; }

  // 2) 前後のタグを原文どおりに付け直す
  const a = affix(en), b = affix(ja);
  cand = a.pre + dropExtra(a.core, b.core) + a.suf;
  if (key(cand) === key(en)) { tm[en] = cand; fixedAffix++; continue; }

  // 3) 落ちたタグを本文の前後に足して数を合わせる（最後の手段）
  const missing = list(en).filter(t => !list(cand).includes(t));
  if (missing.length && missing.every(t => t.startsWith('</'))) {
    cand = cand + missing.join('');
  } else if (missing.length) {
    cand = missing.join('') + cand;
  }
  if (key(cand) === key(en)) { tm[en] = cand; fixedRebuild++; continue; }

  still++;
  if (unfixed.length < 8) unfixed.push(en.slice(0, 70));
}

fs.writeFileSync('tm.json', JSON.stringify(tm, null, 1));
console.log('repaired: extra-dropped', fixedExtra, '/ affix', fixedAffix, '/ rebuilt', fixedRebuild, '/ still broken', still);
unfixed.forEach(s => console.log('  ×', JSON.stringify(s)));
