<?php
declare(strict_types=1);

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

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

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

$userId = isset($_GET['userId']) ? (int) $_GET['userId'] : 0;
if ($userId <= 0) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'bad_request'], JSON_UNESCAPED_UNICODE);
    exit;
}

require_once __DIR__ . '/db.php';
require_once __DIR__ . '/wheel_helpers.php';
require_once __DIR__ . '/admin_user_meta_lib.php';
require_once __DIR__ . '/level_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_user_auth_migrate($pdo);

$st = $pdo->prepare(
    'SELECT u.id, u.username, u.email, u.coins, u.created_at, u.register_ip, u.last_login_ip, u.last_wheel_spin_at,
     COALESCE(u.twofa_enabled, 0) AS twofa_enabled,
     u.telegram_user_id, u.telegram_username, u.telegram_verified_at, u.telegram_pending_expires,
     u.admin_note, u.admin_tags,
     c.btc, c.eth, c.usdt_erc20, c.usdt_trc20, c.ltc, c.trx, c.doge, c.other, c.updated_at AS crypto_updated_at
     FROM users u
     LEFT JOIN user_crypto_wallets c ON c.user_id = u.id
     WHERE u.id = :id LIMIT 1'
);
$st->execute([':id' => $userId]);
$row = $st->fetch();

if (!$row) {
    http_response_code(404);
    echo json_encode(['ok' => false, 'error' => 'not_found'], JSON_UNESCAPED_UNICODE);
    exit;
}

$regIp = isset($row['register_ip']) ? trim((string) $row['register_ip']) : '';
$sameRegisterIpCount = 0;
if ($regIp !== '') {
    $stIp = $pdo->prepare('SELECT COUNT(*) FROM users WHERE register_ip = :ip');
    $stIp->execute([':ip' => $regIp]);
    $sameRegisterIpCount = (int) $stIp->fetchColumn();
}

$st2 = $pdo->prepare(
    'SELECT id, item_id, item_title, price, COALESCE(status, \'pending\') AS status, created_at FROM purchases WHERE user_id = :uid ORDER BY created_at DESC LIMIT 200'
);
$st2->execute([':uid' => $userId]);
$purchases = [];
foreach ($st2->fetchAll() as $p) {
    $purchases[] = [
        'id' => (int) $p['id'],
        'itemId' => $p['item_id'],
        'itemTitle' => $p['item_title'],
        'price' => (int) $p['price'],
        'status' => (string) ($p['status'] ?? 'pending'),
        'createdAt' => (int) $p['created_at'],
    ];
}

$st3 = $pdo->prepare(
    'SELECT sponsor_id, sponsor_title, account_value, updated_at
     FROM user_sponsor_accounts
     WHERE user_id = :uid
     ORDER BY updated_at DESC, sponsor_id ASC
     LIMIT 300'
);
$st3->execute([':uid' => $userId]);
$sponsorAccounts = [];
foreach ($st3->fetchAll() as $r) {
    $sponsorAccounts[] = [
        'sponsorId' => (string) $r['sponsor_id'],
        'sponsorTitle' => $r['sponsor_title'] !== null ? (string) $r['sponsor_title'] : '',
        'accountValue' => $r['account_value'] !== null ? (string) $r['account_value'] : '',
        'updatedAt' => $r['updated_at'] !== null ? (int) $r['updated_at'] : null,
    ];
}

$totalSpent = array_sum(array_column($purchases, 'price'));

$wheelCfg = mocker_wheel_load_config();
$cdSec = $wheelCfg['cooldown_seconds'];
$lastWheel = isset($row['last_wheel_spin_at']) && $row['last_wheel_spin_at'] !== null && $row['last_wheel_spin_at'] !== ''
    ? (int) $row['last_wheel_spin_at']
    : 0;
$now = time();
$wheelNextAt = $lastWheel > 0 ? $lastWheel + $cdSec : 0;
$wheelCanSpin = $lastWheel <= 0 || $now >= $wheelNextAt;

$tgVerifiedAt = $row['telegram_verified_at'] ?? null;
$tgVerified = $tgVerifiedAt !== null && (int) $tgVerifiedAt > 0;
$tgUsername = '';
if ($tgVerified && isset($row['telegram_username']) && $row['telegram_username'] !== null && $row['telegram_username'] !== '') {
    $tgUsername = (string) $row['telegram_username'];
}
$tgUserId = isset($row['telegram_user_id']) && $row['telegram_user_id'] !== null ? (int) $row['telegram_user_id'] : null;
$tgPendingExp = null;
if (!$tgVerified && isset($row['telegram_pending_expires'])) {
    $pe = $row['telegram_pending_expires'];
    if ($pe !== null && (int) $pe > $now) {
        $tgPendingExp = (int) $pe;
    }
}

$blackjackRounds = [];
try {
    $stBj = $pdo->prepare(
        'SELECT id, created_at, bet, doubled, outcome, stake, payout
         FROM blackjack_rounds WHERE user_id = :uid ORDER BY created_at DESC LIMIT 150'
    );
    $stBj->execute([':uid' => $userId]);
    foreach ($stBj->fetchAll(PDO::FETCH_ASSOC) as $br) {
        $blackjackRounds[] = [
            'id' => (int) $br['id'],
            'createdAt' => (int) $br['created_at'],
            'bet' => (int) $br['bet'],
            'doubled' => (int) $br['doubled'] === 1,
            'outcome' => (string) $br['outcome'],
            'stake' => (int) $br['stake'],
            'payout' => (int) $br['payout'],
        ];
    }
} catch (Throwable $e) {
    $blackjackRounds = [];
}

$slotRounds = [];
try {
    $stSlot = $pdo->prepare(
        'SELECT id, created_at, bet, reels_json, multiplier, payout
         FROM slot_rounds WHERE user_id = :uid ORDER BY created_at DESC LIMIT 150'
    );
    $stSlot->execute([':uid' => $userId]);
    foreach ($stSlot->fetchAll(PDO::FETCH_ASSOC) as $sr) {
        $rj = $sr['reels_json'] ?? '[]';
        $decoded = json_decode((string) $rj, true);
        $reels = is_array($decoded) ? $decoded : [];
        $slotRounds[] = [
            'id' => (int) $sr['id'],
            'createdAt' => (int) $sr['created_at'],
            'bet' => (int) $sr['bet'],
            'reels' => $reels,
            'multiplier' => (int) $sr['multiplier'],
            'payout' => (int) $sr['payout'],
        ];
    }
} catch (Throwable $e) {
    $slotRounds = [];
}

$promoRedemptions = [];
try {
    $stPromo = $pdo->prepare(
        'SELECT r.id, r.coins_awarded, r.redeemed_at, p.code
         FROM promo_redemptions r
         INNER JOIN promo_codes p ON p.id = r.promo_code_id
         WHERE r.user_id = :uid
         ORDER BY r.redeemed_at DESC
         LIMIT 150'
    );
    $stPromo->execute([':uid' => $userId]);
    foreach ($stPromo->fetchAll(PDO::FETCH_ASSOC) as $pr) {
        $promoRedemptions[] = [
            'id' => (int) $pr['id'],
            'code' => (string) ($pr['code'] ?? ''),
            'coinsAwarded' => (int) ($pr['coins_awarded'] ?? 0),
            'redeemedAt' => (int) ($pr['redeemed_at'] ?? 0),
        ];
    }
} catch (Throwable $e) {
    $promoRedemptions = [];
}

$ticketEntries = [];
$ticketRequests = [];
try {
    $stTe = $pdo->prepare(
        'SELECT te.id, te.ticket_code, te.is_winner, te.created_at,
                e.id AS event_id, e.title AS event_title, e.sponsor_title, e.status AS event_status
         FROM ticket_entries te
         INNER JOIN ticket_events e ON e.id = te.event_id
         WHERE te.user_id = :uid
         ORDER BY te.created_at DESC
         LIMIT 200'
    );
    $stTe->execute([':uid' => $userId]);
    foreach ($stTe->fetchAll(PDO::FETCH_ASSOC) as $te) {
        $ticketEntries[] = [
            'id' => (int) $te['id'],
            'ticketCode' => (string) $te['ticket_code'],
            'isWinner' => (int) $te['is_winner'] === 1,
            'createdAt' => (int) $te['created_at'],
            'eventId' => (int) $te['event_id'],
            'eventTitle' => (string) ($te['event_title'] ?? ''),
            'sponsorTitle' => (string) ($te['sponsor_title'] ?? ''),
            'eventStatus' => (string) ($te['event_status'] ?? ''),
        ];
    }
    $stTr = $pdo->prepare(
        'SELECT r.id, r.site_username, r.investment_amount, r.investment_at,
                r.tickets_eligible, r.tickets_granted, r.status, r.admin_note,
                r.created_at, r.reviewed_at,
                e.id AS event_id, e.title AS event_title, e.sponsor_title, e.status AS event_status
         FROM ticket_requests r
         INNER JOIN ticket_events e ON e.id = r.event_id
         WHERE r.user_id = :uid
         ORDER BY r.created_at DESC
         LIMIT 200'
    );
    $stTr->execute([':uid' => $userId]);
    foreach ($stTr->fetchAll(PDO::FETCH_ASSOC) as $tr) {
        $ticketRequests[] = [
            'id' => (int) $tr['id'],
            'siteUsername' => (string) ($tr['site_username'] ?? ''),
            'investmentAmount' => (float) ($tr['investment_amount'] ?? 0),
            'investmentAt' => $tr['investment_at'] !== null ? (int) $tr['investment_at'] : null,
            'ticketsEligible' => (int) ($tr['tickets_eligible'] ?? 0),
            'ticketsGranted' => (int) ($tr['tickets_granted'] ?? 0),
            'status' => (string) ($tr['status'] ?? ''),
            'adminNote' => (string) ($tr['admin_note'] ?? ''),
            'createdAt' => (int) ($tr['created_at'] ?? 0),
            'reviewedAt' => $tr['reviewed_at'] !== null ? (int) $tr['reviewed_at'] : null,
            'eventId' => (int) $tr['event_id'],
            'eventTitle' => (string) ($tr['event_title'] ?? ''),
            'sponsorTitle' => (string) ($tr['sponsor_title'] ?? ''),
            'eventStatus' => (string) ($tr['event_status'] ?? ''),
        ];
    }
} catch (Throwable $e) {
    $ticketEntries = [];
    $ticketRequests = [];
}

$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);
$levelProgress = mocker_level_progress_for_user($pdo, $userId);

$crypto = [
    'btc' => $row['btc'] !== null && $row['btc'] !== '' ? (string) $row['btc'] : '',
    'eth' => $row['eth'] !== null && $row['eth'] !== '' ? (string) $row['eth'] : '',
    'usdtErc20' => $row['usdt_erc20'] !== null && $row['usdt_erc20'] !== '' ? (string) $row['usdt_erc20'] : '',
    'usdtTrc20' => $row['usdt_trc20'] !== null && $row['usdt_trc20'] !== '' ? (string) $row['usdt_trc20'] : '',
    'ltc' => $row['ltc'] !== null && $row['ltc'] !== '' ? (string) $row['ltc'] : '',
    'trx' => $row['trx'] !== null && $row['trx'] !== '' ? (string) $row['trx'] : '',
    'doge' => $row['doge'] !== null && $row['doge'] !== '' ? (string) $row['doge'] : '',
    'other' => $row['other'] !== null && $row['other'] !== '' ? (string) $row['other'] : '',
    'updatedAt' => isset($row['crypto_updated_at']) && $row['crypto_updated_at'] !== null ? (int) $row['crypto_updated_at'] : null,
];

header('Content-Type: application/json; charset=utf-8');
echo json_encode(
    [
        'ok' => true,
        'user' => [
            'id' => (int) $row['id'],
            'username' => $row['username'],
            'email' => $row['email'],
            'coins' => (int) $row['coins'],
            'createdAt' => (int) $row['created_at'],
            'totalSpent' => $totalSpent,
            'purchaseCount' => count($purchases),
            'registerIp' => $regIp,
            'lastLoginIp' => isset($row['last_login_ip']) ? trim((string) $row['last_login_ip']) : '',
            'sameRegisterIpCount' => $sameRegisterIpCount,
            'wheelLastSpinAt' => $lastWheel > 0 ? $lastWheel : null,
            'wheelNextSpinAt' => $wheelCanSpin ? null : $wheelNextAt,
            'wheelCanSpin' => $wheelCanSpin,
            'wheelCooldownHours' => $wheelCfg['cooldown_hours'],
            'adminNote' => $adminNote,
            'adminTags' => $adminTags,
            'level' => $levelProgress,
            'twofaEnabled' => (int) ($row['twofa_enabled'] ?? 0) === 1,
        ],
        'level' => $levelProgress,
        'crypto' => $crypto,
        'purchases' => $purchases,
        'sponsorAccounts' => $sponsorAccounts,
        'blackjackRounds' => $blackjackRounds,
        'slotRounds' => $slotRounds,
        'promoRedemptions' => $promoRedemptions,
        'ticketEntries' => $ticketEntries,
        'ticketRequests' => $ticketRequests,
        'telegram' => [
            'verified' => $tgVerified,
            'username' => $tgUsername !== '' ? $tgUsername : null,
            'telegramUserId' => $tgUserId !== null && $tgUserId > 0 ? $tgUserId : null,
            'verifiedAt' => $tgVerified ? (int) $tgVerifiedAt : null,
            'pendingExpiresAt' => $tgPendingExp,
        ],
    ],
    JSON_UNESCAPED_UNICODE
);
