<?php
/**
 * CLI唯一参数：站点根目录。清空点检业务历史，保留设备、条款、班组、菜单和附件文件。
 * 使用当前.env的DATABASE默认连接。先在同库创建备份表，再删除；不重置自增ID。
 * 执行期间应暂停新旧系统的点检写入及消息同步。输入 RESET 数据库名 才会执行。
 */
use think\facade\Db;

if (PHP_SAPI !== 'cli') exit;
if ($argc !== 2) { fwrite(STDERR, "Required argument: site root directory\n"); exit(1); }
$root = rtrim($argv[1], '/\\');
require $root.'/vendor/autoload.php';
$app = new \think\App($root.'/');
$app->initialize();
try {
    $config = Db::connect()->getConfig();
    $prefix = $config['prefix'];
    if (!preg_match('/^[a-zA-Z0-9_]*$/D', $prefix)) throw new RuntimeException('Invalid prefix');
    $pdo = Db::connect()->getPdo();
    $database = $pdo->query('SELECT DATABASE()')->fetchColumn();
    $names = ['me_check_issue_log', 'me_check_issue_flow', 'me_check_issue', 'me_check_record', 'me_check_pause'];
    $tables = [];
    foreach (array_merge($names, ['message']) as $name) {
        $table = $prefix.$name;
        $q = $pdo->prepare('SELECT ENGINE FROM information_schema.tables WHERE table_schema=? AND table_name=?');
        $q->execute([$database, $table]);
        $engine = $q->fetchColumn();
        if (!$engine) {
            if (in_array($name, ['me_check_record','me_check_issue'], true)) throw new RuntimeException('Missing required table: '.$table);
            echo "Skip missing table: $table\n";
            continue;
        }
        if (!in_array(strtoupper($engine), ['MYISAM','INNODB'], true)) throw new RuntimeException('Unsupported engine: '.$table);
        $q = $pdo->prepare('SELECT COUNT(*) FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=? AND REFERENCED_TABLE_NAME IS NOT NULL AND (TABLE_NAME=? OR REFERENCED_TABLE_NAME=?)');
        $q->execute([$database, $table, $table]);
        if ($q->fetchColumn()) throw new RuntimeException('Foreign keys found; manual review required: '.$table);
        $tables[$table] = $name === 'message' ? " WHERE `business`='check-issue'" : '';
    }
    echo "Database: $database; prefix: $prefix\n";
    echo "Clear check records, issues, flow, logs, pauses and check-issue messages.\n";
    echo "Keep equipment, clauses, teams, menus, files and auto-increment counters.\n";
    foreach ($tables as $table=>$where) echo $table.': '.$pdo->query("SELECT COUNT(*) FROM `$table`$where")->fetchColumn()." rows\n";
    echo "Pause check writes/message sync in ALL systems first.\nType RESET $database to continue: ";
    if (trim(fgets(STDIN)) !== 'RESET '.$database) { echo "Cancelled.\n"; exit; }
    \app\mobile\service\CheckSyncGuard::run(true, function() use ($pdo, $tables) {
        $suffix = '_bak_'.date('Ymd_His').'_'.bin2hex(random_bytes(3));
        $backups = [];
        foreach ($tables as $table=>$where) {
            $backup = $table.$suffix;
            if (strlen($backup)>64) throw new RuntimeException('Backup table name exceeds 64 characters');
            $pdo->exec("CREATE TABLE `$backup` LIKE `$table`");
            $backups[$table] = $backup;
            echo "Backup: $table -> $backup\n";
        }
        $locks = [];
        foreach ($backups as $table=>$backup) { $locks[] = "`$table` WRITE"; $locks[] = "`$backup` WRITE"; }
        $pdo->exec('LOCK TABLES '.implode(',', $locks));
        try {
            // 所有表备份且核对成功之后才开始删除，兼容原有MyISAM表。
            foreach ($tables as $table=>$where) {
                $backup = $backups[$table];
                $pdo->exec("INSERT INTO `$backup` SELECT * FROM `$table`$where");
                $count = $pdo->query("SELECT COUNT(*) FROM `$backup`")->fetchColumn();
                if ($count != $pdo->query("SELECT COUNT(*) FROM `$table`$where")->fetchColumn()) throw new RuntimeException('Backup count mismatch: '.$table);
                echo "Backed up $count rows: $backup\n";
            }
            foreach ($tables as $table=>$where) {
                $pdo->exec("DELETE FROM `$table`$where");
                if ($pdo->query("SELECT COUNT(*) FROM `$table`$where")->fetchColumn()) throw new RuntimeException('Reset verification failed: '.$table);
                echo "Cleared: $table\n";
            }
        } finally { $pdo->exec('UNLOCK TABLES'); }
    });
    echo "Database reset complete. Backups retained in this database.\n";
    try { \app\mobile\service\MessageInbox::invalidate(); }
    catch (Throwable $e) { fwrite(STDERR, "Message cache refresh failed; database reset is complete: ".$e->getMessage()."\n"); }
} catch (Throwable $e) {
    fwrite(STDERR, "Stopped: ".$e->getMessage()."\nAny printed backup tables are retained; inspect before retrying.\n");
    exit(1);
}
