<?php
/**
 * 排查 dice_player 删除报错：
 *  - 表结构
 *  - 外键引用情况
 *  - 实际 destroy 流程（不真的删，仅 dry-run 抓异常）
 *
 * 用法：php server/db/inspect_player_destroy.php [<id1>,<id2>,...]
 */
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../support/bootstrap.php';

use support\think\Db;

$config = config('database');
$default = $config['default'];
$conn = $config['connections'][$default];
$dbName = $conn['database'] ?? '';
echo "[DB] {$default} -> {$dbName}\n\n";

echo "--- dice_player columns ---\n";
$cols = Db::query("SHOW FULL COLUMNS FROM `dice_player`");
foreach ($cols as $c) {
    echo str_pad((string)$c['Field'], 26) . ' | ' . str_pad((string)$c['Type'], 24) . ' | NULL=' . $c['Null'] . ' | Key=' . $c['Key'] . "\n";
}
echo "\n";

echo "--- referenced by foreign keys (other tables -> dice_player) ---\n";
$fks = Db::query("SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
    FROM information_schema.KEY_COLUMN_USAGE
    WHERE TABLE_SCHEMA = ? AND REFERENCED_TABLE_NAME = 'dice_player'", [$dbName]);
if (empty($fks)) {
    echo "  (none)\n";
} else {
    foreach ($fks as $f) {
        echo "  {$f['TABLE_NAME']}.{$f['COLUMN_NAME']}  ->  {$f['REFERENCED_TABLE_NAME']}.{$f['REFERENCED_COLUMN_NAME']}   [{$f['CONSTRAINT_NAME']}]\n";
    }
}
echo "\n";

echo "--- top 3 dice_player rows ---\n";
$rows = Db::table('dice_player')->limit(3)->select()->toArray();
foreach ($rows as $r) {
    echo "id={$r['id']} dept_id={$r['dept_id']} username={$r['username']} delete_time=" . ($r['delete_time'] ?? 'null') . "\n";
}
echo "\n";

$idsArg = $argv[1] ?? '';
if ($idsArg === '') {
    echo "(no ids passed, skip dry-run delete)\n";
    return;
}
$ids = array_filter(array_map('intval', explode(',', $idsArg)));
if (empty($ids)) {
    echo "(invalid ids)\n";
    return;
}

echo "--- dry-run destroy ids: " . implode(',', $ids) . " ---\n";
$beforeAll = Db::query('SELECT id, delete_time FROM dice_player WHERE id IN (' . implode(',', array_fill(0, count($ids), '?')) . ')', $ids);
echo "before (raw): " . count($beforeAll) . " rows\n";

$placeholders = implode(',', array_fill(0, count($ids), '?'));

// Case A: static destroy
try {
    Db::startTrans();
    $result = \app\dice\model\player\DicePlayer::destroy($ids, true);
    $afterAny = Db::query("SELECT COUNT(*) AS c FROM dice_player WHERE id IN ({$placeholders})", $ids);
    echo "[static destroy] returned: " . var_export($result, true) . ", remaining raw rows: " . ($afterAny[0]['c'] ?? 'n/a') . "\n";
    Db::rollback();
} catch (\Throwable $e) {
    Db::rollback();
    echo "EXCEPTION (static destroy): " . get_class($e) . ": " . $e->getMessage() . "\n";
}

// Case B: instance ->delete()
try {
    Db::startTrans();
    $instance = \app\dice\model\player\DicePlayer::find($ids[0]);
    if ($instance) {
        $r = $instance->delete();
        $afterAny = Db::query("SELECT COUNT(*) AS c FROM dice_player WHERE id = ?", [$ids[0]]);
        echo "[instance delete] returned: " . var_export($r, true) . ", remaining raw rows for id={$ids[0]}: " . ($afterAny[0]['c'] ?? 'n/a') . "\n";
    } else {
        echo "[instance delete] no instance found for id={$ids[0]}\n";
    }
    Db::rollback();
} catch (\Throwable $e) {
    Db::rollback();
    echo "EXCEPTION (instance delete): " . get_class($e) . ": " . $e->getMessage() . "\n";
}
echo "(both rolled back, no actual delete)\n";
