<?php
declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';
require_once __DIR__ . '/admin_auth_lib.php';

if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
    http_response_code(405);
    echo json_encode(['ok' => false, 'error' => 'method'], JSON_UNESCAPED_UNICODE);
    exit;
}

if (isset($_GET['auditLog']) && (string) $_GET['auditLog'] === '1') {
    mocker_admin_require_permission('audit');
    require_once __DIR__ . '/admin_audit_lib.php';
    mocker_admin_audit_log_send_json_response();
    exit;
}

mocker_admin_require_any_permission(['members', 'ip-clashes']);

require_once __DIR__ . '/db.php';
require_once __DIR__ . '/admin_user_meta_lib.php';
require_once __DIR__ . '/level_lib.php';
require_once __DIR__ . '/external_players_sync_lib.php';
require_once __DIR__ . '/user_auth_lib.php';

try {
    $pdo = mocker_db();
} catch (Throwable $e) {
    http_response_code(503);
    echo json_encode(['ok' => false, 'error' => 'db'], JSON_UNESCAPED_UNICODE);
    exit;
}

mocker_external_players_migrate($pdo);
mocker_level_migrate($pdo);
mocker_user_auth_migrate($pdo);
$levelSettings = mocker_level_get_settings($pdo);
$levelEnabled = !empty($levelSettings['enabled']);
$levelDefs = $levelSettings['levels'];
$levelByUser = [];
foreach ($pdo->query('SELECT user_id, xp_total FROM user_level_state') as $lr) {
    $uidLv = (int) ($lr['user_id'] ?? 0);
    if ($uidLv <= 0) {
        continue;
    }
    $xp = max(0, (int) ($lr['xp_total'] ?? 0));
    $levelByUser[$uidLv] = [
        'enabled' => $levelEnabled,
        'level' => $levelEnabled ? mocker_level_calc_level_from_xp($xp, $levelDefs) : 0,
        'xpTotal' => $levelEnabled ? $xp : 0,
    ];
}
$levelDefault = ['enabled' => $levelEnabled, 'level' => 0, 'xpTotal' => 0];

$rows = $pdo->query(
    'SELECT id, username, email, phone, coins, created_at, register_ip, last_login_ip,
     COALESCE(is_active, 1) AS is_active, COALESCE(twofa_enabled, 0) AS twofa_enabled,
     admin_note, admin_tags, external_player_id, external_synced_at
     FROM users ORDER BY created_at DESC'
)->fetchAll();

$ipRegisterCounts = [];
foreach ($rows as $r) {
    $rip = isset($r['register_ip']) ? trim((string) $r['register_ip']) : '';
    if ($rip !== '') {
        $ipRegisterCounts[$rip] = ($ipRegisterCounts[$rip] ?? 0) + 1;
    }
}

$purchaseStats = [];
foreach (
    $pdo->query(
        'SELECT user_id, COUNT(*) AS cnt, COALESCE(SUM(price), 0) AS spent
         FROM purchases GROUP BY user_id'
    ) as $ps
) {
    $uidPs = (int) ($ps['user_id'] ?? 0);
    if ($uidPs > 0) {
        $purchaseStats[$uidPs] = [
            'count' => (int) ($ps['cnt'] ?? 0),
            'spent' => (int) ($ps['spent'] ?? 0),
        ];
    }
}

$users = [];
foreach ($rows as $row) {
    $uid = (int) $row['id'];
    $extId = isset($row['external_player_id']) ? (int) $row['external_player_id'] : 0;
    $rip = isset($row['register_ip']) ? trim((string) $row['register_ip']) : '';
    $sameRegIp = $rip !== '' ? (int) ($ipRegisterCounts[$rip] ?? 1) : 0;
    $pStats = $purchaseStats[$uid] ?? ['count' => 0, 'spent' => 0];
    $totalSpent = (int) $pStats['spent'];
    $adminNote = isset($row['admin_note']) && $row['admin_note'] !== null ? (string) $row['admin_note'] : '';
    $adminTags = mocker_admin_tags_parse(isset($row['admin_tags']) ? (string) $row['admin_tags'] : null);
    $entry = [
        'id' => $uid,
        'username' => $row['username'],
        'email' => $row['email'],
        'phone' => isset($row['phone']) ? (string) $row['phone'] : '',
        'coins' => (int) $row['coins'],
        'createdAt' => (int) $row['created_at'],
        'totalSpent' => $totalSpent,
        'purchaseCount' => (int) $pStats['count'],
        'registerIp' => $rip,
        'lastLoginIp' => isset($row['last_login_ip']) ? trim((string) $row['last_login_ip']) : '',
        'sameRegisterIpCount' => $sameRegIp,
        'isActive' => (int) ($row['is_active'] ?? 1) === 1,
        'twofaEnabled' => (int) ($row['twofa_enabled'] ?? 0) === 1,
        'adminNote' => $adminNote,
        'adminTags' => $adminTags,
        'level' => $levelByUser[$uid] ?? $levelDefault,
    ];
    if ($extId > 0) {
        $entry['external'] = [
            'source' => 'rx',
            'externalId' => $extId,
            'syncedAt' => isset($row['external_synced_at']) ? (int) $row['external_synced_at'] : 0,
        ];
    }
    $users[] = $entry;
}

$syncStatus = mocker_external_players_sync_status($pdo, mocker_external_players_enabled());

echo json_encode(
    [
        'ok' => true,
        'users' => $users,
        'source' => 'local',
        'sync' => $syncStatus,
    ],
    JSON_UNESCAPED_UNICODE
);
