<?php
declare(strict_types=1);

/**
 * 通过 git diff 恢复 E_XXXXXXXX 对应的原中文，并替换为英文短句：
 * - 在 server 下查找 "'E_XXXXXXXX'" 并替换为 "'<english phrase>'"
 * - 同时写入 resource/translations/api/{en,zh}.php：english=>english / english=>中文
 *
 * 英文短句来源优先级：
 * 1) resource/translations/api/en.php 与 zh.php 中的 MSG_ 对照（中文=>英文）
 * 2) 内置常用中文短语翻译表
 */

$root = dirname(__DIR__);
$repoRoot = dirname($root);

$enPath = $root . '/resource/translations/api/en.php';
$zhPath = $root . '/resource/translations/api/zh.php';

$enMap = is_file($enPath) ? (require $enPath) : [];
$zhMap = is_file($zhPath) ? (require $zhPath) : [];

/** @var array<string, string> $cnToEn 基于 MSG_ 的中文=>英文 */
$cnToEn = [];
foreach ($zhMap as $k => $cn) {
    if (!is_string($k) || !is_string($cn)) {
        continue;
    }
    if (strncmp($k, 'MSG_', 4) !== 0) {
        continue;
    }
    $en = $enMap[$k] ?? null;
    if (is_string($en) && $en !== '') {
        $cnToEn[$cn] = $en;
    }
}

/** 常用中文短语翻译（兜底） */
$fallbackCn = [
    '未查找到信息' => 'not found',
    '记录不存在' => 'record not found',
    '数据不存在' => 'data not found',
    '添加失败' => 'add failed',
    '修改失败' => 'update failed',
    '删除失败' => 'delete failed',
    '参数错误，请检查' => 'invalid parameters, please check',
    '参数错误，请检查参数' => 'invalid parameters, please check',
    '操作失败' => 'operation failed',
    '执行失败' => 'execution failed',
    '请先登录' => 'please login first',
    '未登录' => 'not logged in',
    '下载失败' => 'download failed',
    '请求过于频繁，请稍后再试' => 'too many requests, please try again later',
    '验证码错误' => 'captcha error',
    '请选择要删除的缓存' => 'please select cache to delete',
    '请选择要删除的数据' => 'please select data to delete',
    '请选择要生成的表' => 'please select tables to generate',
    '发送失败，请查看日志' => 'send failed, please check logs',
    '请输入邮箱' => 'please input email',
    '版本ID不能为空' => 'version id is required',
    '上传文件校验失败' => 'upload file validation failed',
    '文件大小不能超过5M' => 'file size cannot exceed 5M',
    '文件格式上传失败,请选择zip格式文件上传' => 'upload failed, please upload zip file',
    '登录已过期或用户信息无效，请重新登录' => 'login expired or invalid, please login again',
    '超级管理员不允许重置密码' => 'super admin cannot reset password',
    '未找到上传文件' => 'uploaded file not found',
    '参数 items 必须为数组' => 'parameter items must be an array',
    '缺少参数 id' => 'missing parameter id',
    '缺少参数 status' => 'missing parameter status',
    '缺少 player_id' => 'missing player_id',
    '缺少参数：agent_id、secret、time、signature 不能为空' => 'missing parameters: agent_id, secret, time, signature are required',
    '无权限查看该记录' => 'no permission to view this record',
    '无权限修改该记录' => 'no permission to update this record',
    '无权限删除所选数据' => 'no permission to delete selected data',
    '无权限操作该玩家' => 'no permission to operate this player',
    '请选择玩家' => 'please select player',
    '操作类型必须为 3=加点 或 4=扣点' => 'operation type must be 3 (add) or 4 (deduct)',
    '请指定测试记录' => 'please specify test record',
    '请传入 record_id' => 'please provide record_id',
    '请传入 direction（0=顺时针 1=逆时针）' => 'please provide direction (0=clockwise, 1=counterclockwise)',
    'direction 必须为 0（顺时针）或 1（逆时针）' => 'direction must be 0 (clockwise) or 1 (counterclockwise)',
    '清空失败：' => 'clear failed: ',
    '管理后台已经安装！如需重新安装，请删除根目录env配置文件并重启' => 'admin already installed, to reinstall please delete env file and restart',
    '数据库用户名或密码错误' => 'database username or password is incorrect',
    'Connection refused. 请确认数据库IP端口是否正确，数据库已经启动' => 'connection refused, please check database ip/port and ensure database is running',
    '数据库连接超时，请确认数据库IP端口是否正确，安全组及防火墙已经放行端口' => 'database connection timeout, please check ip/port and firewall/security group rules',
    '数据库已经安装，请勿重复安装' => 'database already installed, please do not install again',
    '数据库SQL文件不存在' => 'database SQL file not found',
];

$dump = static function (array $arr): string {
    ksort($arr);
    $out = "<?php\ndeclare(strict_types=1);\n\nreturn [\n";
    foreach ($arr as $k => $v) {
        $k = str_replace("'", "\\'", (string) $k);
        $v = str_replace("'", "\\'", (string) $v);
        $out .= "    '{$k}' => '{$v}',\n";
    }
    $out .= "];\n";
    return $out;
};

$diff = shell_exec('git -C ' . escapeshellarg($repoRoot) . ' diff -U0 -- server');
if (!is_string($diff) || $diff === '') {
    echo "no diff\n";
    exit(0);
}

/** @var array<string, string> $hexToCn */
$hexToCn = [];
$lines = preg_split("/\r\n|\n|\r/", $diff) ?: [];
$prevCn = null;
foreach ($lines as $line) {
    // -            return $this->fail('未查找到信息');
    if (preg_match("/^\\-.*'([^']*?)'.*$/u", $line, $m) === 1) {
        $maybeCn = $m[1];
        if (preg_match('/[\x{4e00}-\x{9fff}]/u', $maybeCn) === 1) {
            $prevCn = $maybeCn;
            continue;
        }
    }
    // +            return $this->fail('E_FC6490F8');
    if ($prevCn !== null && preg_match("/^\\+.*'E_([0-9A-Fa-f]{8})'.*$/", $line, $m) === 1) {
        $hexToCn[strtoupper($m[1])] = $prevCn;
        $prevCn = null;
        continue;
    }
    // reset when encountering unrelated added/removed line
    if (strlen($line) > 0 && ($line[0] === '+' || $line[0] === '-')) {
        $prevCn = null;
    }
}

if ($hexToCn === []) {
    echo "no E_ mappings found in diff\n";
    exit(0);
}

// 替换代码中的 E_XXXXXXXX
$serverDir = $root;
$files = [];
$it = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($serverDir, FilesystemIterator::SKIP_DOTS)
);
foreach ($it as $file) {
    /** @var SplFileInfo $file */
    if (!$file->isFile()) {
        continue;
    }
    $path = $file->getPathname();
    if (substr($path, -4) !== '.php') {
        continue;
    }
    $norm = str_replace('\\', '/', $path);
    if (str_contains($norm, '/resource/translations/')) {
        continue;
    }
    if (str_contains($norm, '/scripts/')) {
        continue;
    }
    $files[] = $path;
}

$touched = 0;
$replaced = 0;
$addedPairs = 0;

foreach ($files as $path) {
    $content = file_get_contents($path);
    if (!is_string($content) || $content === '') {
        continue;
    }
    $new = preg_replace_callback(
        "/(['\"])E_([0-9A-Fa-f]{8})\\1/",
        function (array $m) use (&$enMap, &$zhMap, &$replaced, &$addedPairs, $hexToCn, $cnToEn, $fallbackCn) {
            $hex = strtoupper($m[2]);
            $cn = $hexToCn[$hex] ?? null;
            if (!is_string($cn) || $cn === '') {
                return $m[0];
            }

            $en = $cnToEn[$cn] ?? ($fallbackCn[$cn] ?? null);
            if (!is_string($en) || $en === '') {
                return $m[0];
            }

            if (!isset($enMap[$en])) {
                $enMap[$en] = $en;
                $addedPairs++;
            }
            if (!isset($zhMap[$en])) {
                $zhMap[$en] = $cn;
                $addedPairs++;
            }

            $replaced++;
            return "'" . str_replace("'", "\\'", $en) . "'";
        },
        $content
    );

    if (is_string($new) && $new !== $content) {
        file_put_contents($path, $new);
        $touched++;
    }
}

file_put_contents($enPath, $dump($enMap));
file_put_contents($zhPath, $dump($zhMap));

echo "touched_files={$touched}\n";
echo "replaced={$replaced}\n";
echo "added_translation_pairs={$addedPairs}\n";

