const zhFeatureNames = Object.freeze({
  'runtime-patch-001': '源氏秒蓄(长按左键)',
  'runtime-patch-002': '无限蓄力',
  'runtime-patch-003': '幽灵不会消失(技能机制除外,连招派生除外)',
  'runtime-patch-004': '无限 Class 持续时间',
  'runtime-patch-005': '无限热力槽',
  'runtime-patch-006': '一击满魔力漩涡',
  'runtime-patch-007': '无视魔力漩涡限制',
  'runtime-patch-008': '始终最大魔力漩涡',
  'runtime-patch-009': '花耀七闪瞬间满蓄力',
  'runtime-patch-010': '狙击模式快速射击(长按左键然后连按左键)',
  'runtime-patch-011': '无限卢米埃尔之剑 (长按即可)',
  'runtime-patch-012': '无限连招(连点左键派生,然后左右键互点)',
  'runtime-patch-013': '最大技能强化',
  'runtime-patch-014': '防止无痛肉身衰减',
  'runtime-patch-015': '一击集满无痛肉身',
  'runtime-patch-016': '强制触发阿尔贝斯之印',
  'runtime-patch-017': '瞬间直冲拳',
  'runtime-patch-018': '满古今无双流层数不减',
  'runtime-patch-019': '瞬间满古今无双流层数',
  'runtime-patch-020': '瞬间满打击槽',
  'runtime-patch-021': '无限打击层数',
  'runtime-patch-022': '无限龙人化',
  'runtime-patch-023': '一击满异能槽',
  'runtime-patch-024': '瞬间满神愿之力',
  'runtime-patch-025': '神愿之力不掉血',
  'runtime-patch-026': '无限神威一体持续时间',
  'runtime-patch-027': '瞬间进入神威一体',
  'runtime-patch-028': '无限极彩羽翼',
  'runtime-patch-029': '一击满剑神槽与剑光等级',
  'runtime-patch-030': '无限魔眼箭',
  'runtime-patch-031': '无限不灭的群青',
  'runtime-patch-032': '无指针零时反噬',
  'runtime-patch-033': '无限子弹',
  'runtime-patch-034': '铁衣玉碎不减',
  'runtime-patch-035': '无限刃重槽',
  'runtime-patch-036': '最大黑之折跃 (连点右键)',
  'runtime-patch-037': '飞火迅影优化',
  'runtime-patch-038': '无限闪避：',
  'runtime-patch-039': '无限格挡：',
  'runtime-patch-040': '自动完美格挡：',
  'runtime-patch-041': '100% Link time：',
  'runtime-patch-042': '无限道具：',
  'runtime-patch-043': '一击部位破坏：',
  'runtime-patch-044': '无限BOSS破防时间：',
  'runtime-patch-045': '无视召唤限制：',
  'runtime-patch-046': '无视任务限制使用召唤石',
  'runtime-patch-047': '无限挑战时间',
  'runtime-patch-048': '一键发现隐藏的宝箱',
  'runtime-patch-049': '冻结任务倒计时',
  'runtime-patch-050': '自动收集任务宝箱',
  'runtime-patch-051': '无视限制启用战斗辅助',
  'runtime-patch-052': '无视钥匙直接开箱',
  'runtime-patch-053': '跳过结算画面',
  'runtime-patch-054': 'MSP,境界点数不减',
  'runtime-patch-055': '因子合成：强制最高等级',
  'runtime-patch-056': 'CP点不减(新DLC肉鸽副本里的点数)',
  'runtime-patch-057': '突破专精技能上限',
  'runtime-patch-058': '强制获得支线目标奖励',
})

export const runtimePatchEnglishFeatureNames = Object.freeze({
  'runtime-patch-001': 'Instant Genji Charge (Hold Left Click)',
  'runtime-patch-002': 'Unlimited Charge',
  'runtime-patch-003': 'Ghosts Never Disappear (Except Skill Mechanics and Combo Follow-ups)',
  'runtime-patch-004': 'Unlimited Class Duration',
  'runtime-patch-005': 'Unlimited Heat Gauge',
  'runtime-patch-006': 'Max Mystic Vortex in One Hit',
  'runtime-patch-007': 'Ignore Mystic Vortex Restrictions',
  'runtime-patch-008': 'Always Maximum Mystic Vortex',
  'runtime-patch-009': 'Instant Max Charge for Stargaze',
  'runtime-patch-010': 'Sniper Mode Rapid Fire (Hold, Then Repeatedly Click)',
  'runtime-patch-011': 'Unlimited Luminiera Sword (Hold to Continue)',
  'runtime-patch-012': 'Unlimited Combo (Chain Left Click, Then Alternate Left and Right)',
  'runtime-patch-013': 'Maximum Skill Enhancement',
  'runtime-patch-014': 'Prevent Grynoth Decay',
  'runtime-patch-015': 'Max Grynoth in One Hit',
  'runtime-patch-016': 'Always Apply Arvess Fermare',
  'runtime-patch-017': 'Instant Charged Punch',
  'runtime-patch-018': 'Maximum Eternal Rage Stacks Do Not Decrease',
  'runtime-patch-019': 'Instant Maximum Eternal Rage Stacks',
  'runtime-patch-020': 'Instant Full Beatdown Gauge',
  'runtime-patch-021': 'Unlimited Beatdown Stacks',
  'runtime-patch-022': 'Unlimited Dragonform',
  'runtime-patch-023': 'Full Versalis Gauge in One Hit',
  'runtime-patch-024': 'Instant Full Godmight',
  'runtime-patch-025': 'Godmight Does Not Drain HP',
  'runtime-patch-026': 'Unlimited Godmight Duration',
  'runtime-patch-027': 'Enter Godmight Instantly',
  'runtime-patch-028': 'Unlimited Chromatic Wings',
  'runtime-patch-029': 'Max Sword Avatar Gauge and Swordshine in One Hit',
  'runtime-patch-030': 'Unlimited Magic-Eye Arrows',
  'runtime-patch-031': 'Unlimited Immortal Azure',
  'runtime-patch-032': 'Zero-Hour Counter Without Clock Hand',
  'runtime-patch-033': 'Unlimited Ammo',
  'runtime-patch-034': 'Iron Body Stacks Do Not Decrease',
  'runtime-patch-035': 'Unlimited Blade Weight Gauge',
  'runtime-patch-036': 'Maximum Black Shift (Repeatedly Right Click)',
  'runtime-patch-037': 'Improved Wingclipper Follow-up',
  'runtime-patch-038': 'Unlimited Dodges:',
  'runtime-patch-039': 'Unlimited Blocks:',
  'runtime-patch-040': 'Automatic Perfect Block:',
  'runtime-patch-041': '100% Link Time:',
  'runtime-patch-042': 'Unlimited Items:',
  'runtime-patch-043': 'One-Hit Part Break:',
  'runtime-patch-044': 'Unlimited Boss Break Duration:',
  'runtime-patch-045': 'Ignore Summon Restrictions:',
  'runtime-patch-046': 'Use Summons Regardless of Quest Restrictions',
  'runtime-patch-047': 'Unlimited Challenge Time',
  'runtime-patch-048': 'Reveal Hidden Chests Instantly',
  'runtime-patch-049': 'Freeze Quest Countdown',
  'runtime-patch-050': 'Automatically Collect Quest Chests',
  'runtime-patch-051': 'Enable Assist Mode Regardless of Restrictions',
  'runtime-patch-052': 'Open Chests Without Keys',
  'runtime-patch-053': 'Skip Results Screen',
  'runtime-patch-054': 'MSP and Boundary Points Do Not Decrease',
  'runtime-patch-055': 'Sigil Synthesis: Force Maximum Level',
  'runtime-patch-056': 'CP Does Not Decrease (DLC Roguelike Quests)',
  'runtime-patch-057': 'Remove Mastery Skill Cap',
  'runtime-patch-058': 'Force Side-Objective Rewards',
})

const groupEnglishNames = Object.freeze({
  '娜露梅': 'Narmaya',
  '角色修改': 'General Character',
  '菲莉': 'Ferry',
  '古兰': 'Gran',
  '拉卡姆': 'Rackam',
  '伊欧': 'Io',
  '欧根': 'Eugen',
  '夏洛特': 'Charlotta',
  '尤达哈拉': 'Yodarha',
  '巴萨拉卡': 'Vaseraga',
  '泽塔': 'Zeta',
  '冈达葛萨': 'Ghandagoza',
  '巴恩': 'Vane',
  '伊德': 'Id',
  '圣德芬': 'Sandalphon',
  '希耶提': 'Seofon',
  '索恩': 'Tweyen',
  '贝阿朵丽丝': 'Beatrix',
  '尤斯蒂斯': 'Eustace',
  '伽兰查': 'Gallanza',
  '玛琪拉菲菈': 'Maglielle',
  '菲迪埃尔': 'Fediel',
  '战斗功能': 'Combat Rules',
  '任务修改': 'Quest Rules',
  '体验优化': 'Convenience',
  '其他': 'Other',
})

const textEnglish = Object.freeze({
  '这些功能会直接修改游戏运行时规则。请确认当前不在联机房间，并只在离线或单机内容中使用。本次打开应用只确认一次。': 'These features directly modify runtime game rules. Confirm that you are not in an online room and use them only in offline or single-player content. This confirmation is required once per app session.',
  '角色机制': 'Character Mechanics',
  '按真实角色分组的专属机制；搜索后只显示匹配角色与功能。': 'Character-specific mechanics grouped by the real roster; search shows only matching characters and features.',
  '闪避、格挡、Link、召唤限制与部位破坏等通用战斗规则。': 'General combat rules for dodges, blocks, Link, summon restrictions, part breaks, and more.',
  '任务倒计时、宝箱、结算、支线奖励与养成便利。': 'Quest timers, chests, results, side-objective rewards, and progression conveniences.',
  '安全断开暂未完成，正在后台重试恢复：': 'Safe disconnect is not complete; restoration is retrying in the background: ',
  '全部实时补丁已恢复，并已断开游戏进程': 'All live patches were restored and the game process was disconnected',
  '功能目录已就绪；连接游戏后可读取实时状态。': 'The feature catalog is ready. Connect to the game to read live status.',
  '读取实时功能目录失败：': 'Failed to load the live feature catalog: ',
  '实时功能目录格式无效': 'Invalid live feature catalog format',
  '；释放连接也失败：': '; releasing the connection also failed: ',
  '后端未返回连接所有权令牌': 'The backend did not return a connection owner token',
  '当前页面不再持有连接所有权': 'This page no longer owns the connection',
  '换一个角色名、功能名或分组关键词。': 'Try another character, feature, or group keyword.',
  '与「': 'Conflicts with “',
  '」互斥；先恢复该功能后才能启用。': '”. Restore that feature before enabling this one.',
  '首次启用时定位并保存原字节': 'Locate and retain original bytes on first enable',
  '确认仅在单机使用并开启': 'Confirm Single-Player Use and Enable',
  '正在读取实时功能目录…': 'Loading the live feature catalog…',
  '正在安全恢复并断开': 'Safely Restoring and Disconnecting',
  '连接游戏后读取实时状态': 'Connect to Read Live Status',
  '搜索名称、角色或分组': 'Search Names, Characters, or Groups',
  '输入关键词筛选': 'Enter Keywords to Filter',
  '正在读取功能目录…': 'Loading Feature Catalog…',
  '没有匹配的功能': 'No Matching Features',
  '首次启用确认': 'First Enable Confirmation',
  '仅离线/单机使用': 'Offline / Single-Player Only',
  '实时补丁状态已回读': 'Live patch status was read back',
  '写后回读状态不一致': ' read-back state does not match after writing',
  '操作失败：': ' operation failed: ',
  '已连接游戏进程 PID ': 'Connected to game process PID ',
  '刷新状态失败：': 'Failed to refresh status: ',
  '重试安全恢复': 'Retry Safe Restoration',
  '恢复全部并断开': 'Restore All and Disconnect',
  '连接游戏进程': 'Connect to Game Process',
  '游戏进程已连接': 'Game Process Connected',
  '三个补丁页共用此连接；切换页面时保持常驻。': 'All three patch pages share this connection and remain active while navigating.',
  '已验证连接': 'Verified Connection',
  '等待恢复': 'Waiting for Restoration',
  '刷新状态': 'Refresh Status',
  '处理中…': 'Working…',
  '回读中…': 'Reading Back…',
  '回读中': 'Reading Back',
  '已回读 ': 'Read back ',
  ' 个写入点': ' write sites',
  '连接后读取状态': 'Read status after connecting',
  '战斗规则目录': 'Combat Rules Catalog',
  '任务与便利目录': 'Quest & Convenience Catalog',
  '角色机制目录': 'Character Mechanics Catalog',
  '战斗规则分组': 'Combat Rules Groups',
  '任务与便利分组': 'Quest & Convenience Groups',
  '角色机制分组': 'Character Mechanics Groups',
  '战斗规则': 'Combat Rules',
  '任务与便利': 'Quest & Convenience',
  ' 项已验证补丁': ' verified patches',
  '已读取 ': 'Loaded ',
  ' 项': ' items',
  '已开启 ': 'Enabled ',
  '项': 'items',
  '需要恢复': 'Restoration Required',
  '未连接': 'Not Connected',
  '互斥占用': 'Conflicting Feature Active',
  '不可用': 'Unavailable',
  '已开启': 'Enabled',
  '已恢复默认': 'Restored Default',
  '恢复默认': 'Restore Default',
  '默认': 'Default',
  '开启': 'Enable',
  '当前分组': 'Current Group',
  '技术详情': 'Technical Details',
  '项已验证补丁': 'verified patches',
  '目录 ID': 'Catalog ID',
  '写入点': 'Write Sites',
  '冲突组': 'Conflict Group',
  '目录': 'Catalog',
  '分组': 'Groups',
  '功能': 'Features',
  '偏移': 'Offset',
  '当前字节': 'Current Bytes',
  '偏移 ': 'Offset ',
  '当前字节 ': 'Current Bytes ',
  '未读取': 'Not Read',
  '即将开启': 'About to Enable',
  '取消': 'Cancel',
  '未知错误': 'Unknown Error',
  '实时功能目录': 'live feature catalog',
  '实时补丁回读状态': 'live patch read-back status',
  '目录与回读状态必须是数组': 'catalog and read-back statuses must be arrays',
  '功能目录 ID 必须非空且唯一': 'feature catalog IDs must be non-empty and unique',
  '回读状态数量与目录不一致': 'read-back status count does not match the catalog',
  '回读状态 ID 不能为空': 'read-back status ID cannot be empty',
  '回读状态 ID 重复：': 'duplicate read-back status ID: ',
  '回读状态包含目录外 ID：': 'read-back status contains an unknown catalog ID: ',
  '回读状态 ': 'read-back status ',
  '功能目录 ': 'feature catalog ',
  ' 的 enabled 必须是布尔值': ' enabled must be a boolean',
  ' 的 available 必须是布尔值': ' available must be a boolean',
  ' 的 error 必须是字符串': ' error must be a string',
  ' 的 rvas 必须是数组': ' rvas must be an array',
  ' 的 currentBytes 必须是数组': ' currentBytes must be an array',
  ' 的 rvas 与 currentBytes 长度必须一致': ' rvas and currentBytes must have equal lengths',
  ' 的写入点数量与目录不一致': ' write-site count does not match the catalog',
  ' 的 RVA[': ' RVA[',
  ' 的当前字节[': ' current bytes[',
  ' 必须是非负安全整数': ' must be a non-negative safe integer',
  ' 必须是空值或空格分隔的十六进制字节': ' must be empty or space-separated hexadecimal bytes',
  ' 的补丁字节无效': ' patch bytes are invalid',
  '2.0.2 现场验证通过：待机与连招受击流程均正常，连招中连续受击 3 次未再中断自动完美格挡。': 'Verified in game 2.0.2: idle and mid-combo hit tests passed, with three consecutive combo-state hits no longer interrupting automatic perfect guard.',
  ' 长度与目录补丁不一致': ' length does not match the catalog patch',
  ' 已开启却没有持有写入点': ' is enabled without owned write sites',
  ' 已开启时 available 必须为 true': ' must be available when enabled',
  ' 已开启时 error 必须为空': ' must have no error when enabled',
  ' 已开启，但当前字节[': ' is enabled, but current bytes[',
  '] 与目录补丁不一致': '] do not match the catalog patch',
})

const featureTextReplacements = Object.freeze(Object.fromEntries(
  Object.keys(zhFeatureNames).flatMap((id) => {
    const zh = zhFeatureNames[id]
    const en = runtimePatchEnglishFeatureNames[id]
    const trimmedZH = zh.replace(/[：:]\s*$/u, '')
    const trimmedEN = en.replace(/:\s*$/u, '')
    return trimmedZH === zh ? [[zh, en]] : [[zh, en], [trimmedZH, trimmedEN]]
  }),
))

const englishReplacements = Object.freeze(Object.entries({
  ...featureTextReplacements,
  ...groupEnglishNames,
  ...textEnglish,
}).sort(([left], [right]) => right.length - left.length))

export function translateRuntimePatchFeatureName(feature, locale = 'zh') {
  const source = String(feature?.displayName || feature?.name || '').replace(/[：:]\s*$/u, '')
  if (locale !== 'en') return source
  return String(runtimePatchEnglishFeatureNames[String(feature?.id || '')] || source).replace(/:\s*$/u, '')
}

export function translateRuntimePatchGroupName(group, locale = 'zh') {
  const source = String(group ?? '')
  return locale === 'en' ? groupEnglishNames[source] || source : source
}

export function translateRuntimePatchText(value, locale = 'zh') {
  let output = String(value ?? '')
  if (locale !== 'en') return output
  for (const [source, translated] of englishReplacements) output = output.split(source).join(translated)
  return output
}
