<?php
// admin_panel.php - Panel Administrasi Terpisah
require 'config.php';
$ip = $_SERVER['REMOTE_ADDR'];
$endpoint = 'page.admin_panel'; // ganti nama sesuai file
if (!checkRateLimitApi($pdo, $ip, $endpoint, 120, 60)) {
    http_response_code(429);
    die('<div style="text-align:center;padding:50px;"><h1>429 Too Many Requests</h1><p>Terlalu banyak permintaan. Silakan coba lagi setelah 1 menit.</p></div>');
}

// Cek login dan role admin
if (!isset($_SESSION['user_id']) || $_SESSION['is_admin'] != 1) {
    header('Location: index.php');
    exit;
}

$adminName = $_SESSION['username'];
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Admin Panel - FIFA World Cup 2026</title>
    <meta name="csrf-token" content="<?php echo $_SESSION['csrf_token']; ?>">
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap"
        rel="stylesheet">
    <style>
        /* (CSS sama seperti sebelumnya, tidak diubah) */
        body {
            background: #030610;
            font-family: 'Inter', sans-serif;
        }

        .glass-card {
            background: rgba(255, 255, 255, 0.02);
            backdrop-filter: blur(12px);
            border: 1px solid rgba(255, 255, 255, 0.05);
            border-radius: 2rem;
            transition: all 0.3s;
        }

        .glass-card:hover {
            background: rgba(255, 255, 255, 0.04);
            border-color: rgba(255, 255, 255, 0.1);
        }

        .nav-link {
            @apply relative py-2 px-4 transition-all duration-300 text-slate-500 font-bold uppercase tracking-widest text-[9px];
        }

        .nav-link.active {
            @apply text-amber-500;
        }

        .table-container {
            overflow-x: auto;
        }

        table {
            width: 100%;
            border-collapse: collapse;
        }

        th,
        td {
            padding: 12px 8px;
            text-align: left;
            border-bottom: 1px solid rgba(255, 255, 255, 0.1);
        }

        th {
            color: #f59e0b;
            font-size: 0.7rem;
            text-transform: uppercase;
            letter-spacing: 0.1em;
        }

        select,
        input {
            background: #0f172a;
            border: 1px solid #334155;
            border-radius: 0.75rem;
            padding: 0.5rem;
            color: white;
            cursor: pointer;
        }

        select option {
            background: #1e293b;
        }

        button {
            transition: all 0.2s;
        }

        .toast {
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: #1e293b;
            backdrop-filter: blur(12px);
            border: 1px solid #f59e0b;
            border-radius: 2rem;
            padding: 0.75rem 1.5rem;
            color: white;
            z-index: 1000;
            font-weight: bold;
        }

        .overflow-x-auto {
            overflow-x: auto;
            -webkit-overflow-scrolling: touch;
        }

        .match-status-badge {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            padding: 8px 20px;
            border-radius: 40px;
            font-size: 14px;
            font-weight: 900;
            text-transform: uppercase;
            letter-spacing: 1px;
            gap: 8px;
            transition: all 0.2s ease;
        }

        .status-selesai {
            background: linear-gradient(135deg, rgba(34, 197, 94, 0.25), rgba(34, 197, 94, 0.1));
            color: #22c55e;
            border: 2px solid #22c55e;
            box-shadow: 0 0 12px rgba(34, 197, 94, 0.4);
        }

        .status-belum {
            background: linear-gradient(135deg, rgba(156, 163, 175, 0.2), rgba(156, 163, 175, 0.05));
            color: #9ca3af;
            border: 2px solid #4b5563;
        }

        .status-live {
            background: linear-gradient(135deg, rgba(239, 68, 68, 0.3), rgba(239, 68, 68, 0.1));
            color: #ef4444;
            border: 2px solid #ef4444;
            animation: pulseRed 1.5s infinite;
            box-shadow: 0 0 15px rgba(239, 68, 68, 0.5);
        }

        @keyframes pulseRed {
            0% {
                opacity: 0.8;
                transform: scale(1);
            }

            50% {
                opacity: 1;
                transform: scale(1.02);
                background: rgba(239, 68, 68, 0.2);
            }

            100% {
                opacity: 0.8;
                transform: scale(1);
            }
        }

        .status-highlight {
            background: rgba(0, 0, 0, 0.3);
            border-radius: 60px;
            padding: 4px 12px;
            border: 1px dashed rgba(255, 255, 255, 0.2);
        }
    </style>
</head>

<body class="min-h-screen text-white">

    <!-- Navbar -->
    <nav class="sticky top-0 z-50 px-4 pt-4">
        <div class="max-w-7xl mx-auto glass-card rounded-[40px] px-5 sm:px-10 h-20 flex items-center justify-between">
            <div class="flex items-center gap-2 cursor-pointer" onclick="window.location.href='index.php'">
                <img src="fifa-world-cup-2026-logo-white.png" alt="Logo" class="h-10 w-auto">
                <span class="text-xs font-black text-white tracking-wider">WORLD CUP 2026</span>
            </div>
            <div class="flex items-center gap-4">
                <div class="text-right hidden sm:block">
                    <span class="block text-[10px] font-black text-white uppercase">
                        <?php echo htmlspecialchars($adminName); ?>
                    </span>
                    <span class="block text-[8px] text-amber-500">Administrator</span>
                </div>
                <a href="index.php"
                    class="bg-white/10 px-4 py-2 rounded-full text-xs font-black hover:bg-white/20 transition">Beranda</a>
                <a href="stats.php"
                    class="bg-white/10 px-4 py-2 rounded-full text-xs font-black hover:bg-white/20 transition">Statistik</a>
                <a href="reports.php"
                    class="bg-white/10 px-4 py-2 rounded-full text-xs font-black hover:bg-white/20 transition">Laporan</a>
                <a href="auth.php?action=logout"
                    class="bg-red-500/20 px-4 py-2 rounded-full text-xs font-black hover:bg-red-500/40">Logout</a>
            </div>
        </div>
    </nav>

    <main class="max-w-7xl mx-auto px-4 py-8">
        <div class="text-center mb-8">
            <h1 class="text-4xl md:text-6xl font-black uppercase tracking-tighter">Panel <span
                    class="text-amber-500">Admin</span></h1>
            <p class="text-slate-400 text-sm mt-2">Manajemen pertandingan, tiket, poin, dan hadiah</p>
        </div>

        <!-- Tab Navigasi -->
        <div class="flex flex-wrap justify-center gap-3 mb-8">
            <button data-tab="users"
                class="tab-btn active bg-amber-500 text-black px-5 py-2 rounded-full text-sm font-black">👥 Akun Member
            </button>
            <button data-tab="group"
                class="tab-btn bg-white/5 text-white/70 px-5 py-2 rounded-full text-sm font-black">🏆 Pertandingan
                Grup</button>
            <button data-tab="knockout"
                class="tab-btn bg-white/5 text-white/70 px-5 py-2 rounded-full text-sm font-black">🥇 Pertandingan
                Penyisihan</button>
            <button data-tab="ticket-codes"
                class="tab-btn bg-white/5 text-white/70 px-5 py-2 rounded-full text-sm font-black">🎫 Kode
                Tiket</button>
            <button data-tab="point-logs"
                class="tab-btn bg-white/5 text-white/70 px-5 py-2 rounded-full text-sm font-black">📜 Log Penukaran
                Poin</button>
            <button data-tab="leaderboard"
                class="tab-btn bg-white/5 text-white/70 px-5 py-2 rounded-full text-sm font-black">🏆 Peringkat 10
                Besar</button>
            <button data-tab="rewards"
                class="tab-btn bg-white/5 text-white/70 px-5 py-2 rounded-full text-sm font-black">🎁 Manajemen
                Hadiah</button>

        </div>

        <!-- Tab Users & Tiket -->
        <div id="tab-users" class="tab-content glass-card p-6 rounded-3xl">
            <h3 class="text-xl font-black mb-4">Manajemen User, Tiket & Poin</h3>
            <div class="flex flex-wrap gap-2 mb-4">
                <input type="text" id="search-user-input" placeholder="Cari username..."
                    class="flex-1 min-w-[150px] bg-white/5 border border-white/10 rounded-xl px-4 py-2 text-sm">
                <button id="search-user-btn"
                    class="bg-amber-500/20 hover:bg-amber-500/30 text-amber-400 px-4 py-2 rounded-xl text-xs font-black">Cari</button>
                <button id="reset-user-btn"
                    class="bg-white/5 hover:bg-white/10 text-white px-4 py-2 rounded-xl text-xs font-black">Reset</button>
            </div>
            <div id="user-tickets-list" class="overflow-x-auto">
                <div class="text-center py-4 text-slate-400">🔍 Masukkan username dan klik Cari untuk menampilkan data.
                </div>
            </div>
            <div id="user-pagination" class="flex justify-center gap-2 mt-6"></div>

            <!-- 10 User Terakhir Bergabung -->
            <div class="mt-8">
                <h4 class="text-lg font-black mb-3">🕒 10 User Terakhir Bergabung</h4>
                <div id="latest-users-list" class="overflow-x-auto">
                    <div class="text-center py-4 text-slate-400">Memuat data...</div>
                </div>
            </div>
        </div>

        <!-- Tab Group Matches -->
        <div id="tab-group" class="tab-content hidden glass-card p-6 rounded-3xl">
            <div class="flex flex-wrap justify-between items-center mb-4">
                <h3 class="text-xl font-black">Kelola Pertandingan Grup</h3>
                <button id="create-group-btn"
                    class="bg-green-500/80 hover:bg-green-500 text-black px-4 py-2 rounded-xl text-xs font-black">+ Buat
                    Baru</button>
            </div>
            <div class="flex flex-wrap gap-4 items-end mb-4">
                <div class="flex-1 min-w-[200px]">
                    <label class="text-[9px] font-black text-slate-500 uppercase">Pilih Pertandingan</label>
                    <select id="admin-group-select"
                        class="w-full bg-white/5 border border-white/10 rounded-xl py-2 px-3"></select>
                </div>
                <button id="load-group-match"
                    class="bg-amber-500 text-black px-4 py-2 rounded-xl text-xs font-black">Load</button>
            </div>
            <div id="group-edit-form" class="hidden border-t border-white/10 pt-4 mt-2"></div>
            <div id="group-create-form" class="hidden border-t border-white/10 pt-4 mt-2"></div>
        </div>

        <!-- Tab Knockout Matches -->
        <div id="tab-knockout" class="tab-content hidden glass-card p-6 rounded-3xl">
            <h3 class="text-xl font-black mb-4">Kelola Pertandingan Knockout</h3>
            <div class="flex flex-wrap gap-4 items-end mb-4">
                <div class="flex-1 min-w-[200px]">
                    <label class="text-[9px] font-black text-slate-500 uppercase">Pilih Pertandingan</label>
                    <select id="admin-knockout-select"
                        class="w-full bg-white/5 border border-white/10 rounded-xl py-2 px-3"></select>
                </div>
                <button id="load-knockout-match"
                    class="bg-amber-500 text-black px-4 py-2 rounded-xl text-xs font-black">Load</button>
            </div>
            <div id="knockout-edit-form" class="hidden border-t border-white/10 pt-4 mt-2"></div>
        </div>

        <!-- Tab Ticket Codes -->
        <div id="tab-ticket-codes" class="tab-content hidden glass-card p-6 rounded-3xl">
            <h3 class="text-xl font-black mb-4">Buat Kode Tiket Baru</h3>
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
                <input type="number" id="admin-ticket-amount" placeholder="Jumlah tiket"
                    class="bg-white/5 border border-white/10 rounded-xl px-4 py-2">
                <input type="number" id="admin-max-uses" placeholder="Maksimal penggunaan (1 jika kosong)"
                    class="bg-white/5 border border-white/10 rounded-xl px-4 py-2">
                <input type="datetime-local" id="admin-expires-at"
                    class="bg-white/5 border border-white/10 rounded-xl px-4 py-2">
            </div>
            <button id="generate-ticket-code-btn"
                class="bg-amber-500 text-black px-6 py-3 rounded-xl text-xs font-black">Buat Kode</button>
            <div id="ticket-codes-list" class="mt-6 overflow-x-auto">
                <div class="text-center py-4 text-slate-400">Memuat daftar kode...</div>
            </div>
        </div>

        <!-- Tab Point Redeems Log -->
        <div id="tab-point-logs" class="tab-content hidden glass-card p-6 rounded-3xl">
            <div class="flex justify-between items-center mb-4">
                <h3 class="text-xl font-black">Riwayat Penukaran Poin</h3>
                <button id="refresh-point-logs"
                    class="bg-amber-500/20 hover:bg-amber-500/30 text-amber-400 px-4 py-2 rounded-xl text-xs font-black">Refresh</button>
            </div>
            <div id="point-redeems-log" class="overflow-x-auto">
                <div class="text-center py-4 text-slate-400">Memuat data...</div>
            </div>
        </div>

        <!-- Tab Leaderboard 10 Besar (Live) -->
        <div id="tab-leaderboard" class="tab-content hidden glass-card p-6 rounded-3xl">
            <div class="flex flex-wrap justify-between items-center mb-4">
                <h3 class="text-xl font-black">🏆 10 Besar Leaderboard (Live)</h3>
                <div class="flex gap-3">
                    <button id="force-snapshot-btn"
                        class="bg-amber-500/20 hover:bg-amber-500/30 text-amber-400 px-4 py-2 rounded-xl text-xs font-black flex items-center gap-2">
                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
                        </svg>
                        Update Snapshot Sekarang
                    </button>
                    <button id="delete-snapshots-btn"
                        class="bg-red-500/20 hover:bg-red-500/30 text-red-400 px-4 py-2 rounded-xl text-xs font-black flex items-center gap-2">
                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                        </svg>
                        Hapus Semua Snapshot
                    </button>
                </div>
            </div>

            <div id="leaderboard-list" class="overflow-x-auto">
                <div class="text-center py-4 text-slate-400">Memuat leaderboard...</div>
            </div>
        </div>
        <!-- Tab Manajemen Hadiah -->
        <div id="tab-rewards" class="tab-content hidden glass-card p-6 rounded-3xl">
            <div class="flex justify-between items-center mb-4">
                <h3 class="text-xl font-black">Manajemen Hadiah (Rewards)</h3>
                <button id="refresh-rewards-btn"
                    class="bg-amber-500/20 hover:bg-amber-500/30 text-amber-400 px-4 py-2 rounded-xl text-xs font-black">Refresh</button>
            </div>
            <div id="rewards-list-container" class="overflow-x-auto">
                <div class="text-center py-4 text-slate-400">Memuat data hadiah...</div>
            </div>
        </div>
    </main>

    <div id="toast" class="toast hidden"></div>

    <!-- MODAL UBAH PASSWORD USER -->
    <div id="password-modal"
        class="fixed inset-0 z-[300] hidden items-center justify-center p-4 bg-black/80 backdrop-blur-xl transition-all duration-300">
        <div class="relative w-full max-w-md glass-card rounded-3xl border border-amber-500/30 overflow-hidden">
            <div class="absolute top-0 right-0 p-4">
                <button onclick="closePasswordModal()" class="text-slate-400 hover:text-white">
                    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                            d="M6 18L18 6M6 6l12 12" />
                    </svg>
                </button>
            </div>
            <div class="p-6 sm:p-8 space-y-4">
                <h3 class="text-xl font-black text-white text-center">Ubah Password User</h3>
                <p id="password-modal-username" class="text-center text-amber-500 font-bold">-</p>
                <input type="password" id="new-password" placeholder="Password baru (minimal 6 karakter)"
                    class="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-3 text-white">
                <input type="password" id="confirm-password" placeholder="Konfirmasi password baru"
                    class="w-full bg-white/5 border border-white/10 rounded-xl px-4 py-3 text-white">
                <div id="password-error" class="text-red-400 text-xs hidden"></div>
                <div class="flex gap-3">
                    <button onclick="submitPasswordChange()"
                        class="flex-1 bg-amber-500 text-black py-3 rounded-xl font-black">Simpan</button>
                    <button onclick="closePasswordModal()"
                        class="flex-1 bg-white/10 text-white py-3 rounded-xl font-black">Batal</button>
                </div>
            </div>
        </div>
    </div>

    <script>
        const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
        let allUsers = [];
        let allTeams = [];
        let allGroups = [];
        let groupMatches = [];
        let knockoutMatches = [];
        let currentUserFilter = '';
        let currentTicketCodePage = 1;
        let currentPointLogPage = 1;
        const TICKET_LIMIT = 10;
        const POINT_LIMIT = 20;

        let usersPerPage = 10;
        let currentUserPage = 1;
        let totalUserPages = 1;
        let filteredUsers = [];
        let hasUserSearch = false;

        let currentPasswordUserId = null;
        let currentPasswordUsername = '';

        // ========== FUNGSI KONVERSI UTC KE WIB ==========
        function formatWIB(utcDateStr) {
            if (!utcDateStr) return '';
            // Jika hanya tanggal (format YYYY-MM-DD), kembalikan asli (tidak perlu konversi zona waktu)
            if (/^\d{4}-\d{2}-\d{2}$/.test(utcDateStr)) {
                return utcDateStr;
            }
            // Pastikan string dianggap UTC dengan menambahkan 'Z' jika belum ada
            let dateStr = utcDateStr.includes('Z') ? utcDateStr : utcDateStr + 'Z';
            const date = new Date(dateStr);
            if (isNaN(date.getTime())) return utcDateStr;
            return date.toLocaleString('id-ID', {
                timeZone: 'Asia/Jakarta',
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit'
            });
        }

        function changeUserPassword(userId, username) {
            currentPasswordUserId = userId;
            currentPasswordUsername = username;
            document.getElementById('password-modal-username').innerText = `User: ${username}`;
            document.getElementById('new-password').value = '';
            document.getElementById('confirm-password').value = '';
            document.getElementById('password-error').classList.add('hidden');
            document.getElementById('password-modal').classList.remove('hidden');
            document.getElementById('password-modal').classList.add('flex');
        }

        function closePasswordModal() {
            document.getElementById('password-modal').classList.add('hidden');
            document.getElementById('password-modal').classList.remove('flex');
            currentPasswordUserId = null;
        }

        async function submitPasswordChange() {
            const newPass = document.getElementById('new-password').value.trim();
            const confirmPass = document.getElementById('confirm-password').value.trim();
            const errorDiv = document.getElementById('password-error');

            if (newPass.length < 6) {
                errorDiv.innerText = 'Password minimal 6 karakter.';
                errorDiv.classList.remove('hidden');
                return;
            }
            if (newPass !== confirmPass) {
                errorDiv.innerText = 'Konfirmasi password tidak cocok.';
                errorDiv.classList.remove('hidden');
                return;
            }

            const formData = new FormData();
            formData.append('user_id', currentPasswordUserId);
            formData.append('new_password', newPass);

            try {
                const res = await fetch('api.php?action=admin_change_password', {
                    method: 'POST',
                    body: formData,
                    headers: { 'X-CSRF-TOKEN': csrfToken }
                });
                const data = await res.json();
                if (data.status === 'success') {
                    showToast(`Password user ${currentPasswordUsername} berhasil diubah.`, false);
                    closePasswordModal();
                } else {
                    errorDiv.innerText = data.error || 'Gagal mengubah password.';
                    errorDiv.classList.remove('hidden');
                }
            } catch (err) {
                errorDiv.innerText = 'Terjadi kesalahan jaringan.';
                errorDiv.classList.remove('hidden');
            }
        }

        function formatLocalDateTime(isoString) {
            if (!isoString) return '';
            const d = new Date(isoString);
            if (isNaN(d.getTime())) return '';
            const year = d.getFullYear();
            const month = String(d.getMonth() + 1).padStart(2, '0');
            const day = String(d.getDate()).padStart(2, '0');
            const hours = String(d.getHours()).padStart(2, '0');
            const minutes = String(d.getMinutes()).padStart(2, '0');
            return `${year}-${month}-${day}T${hours}:${minutes}`;
        }

        function showToast(msg, isError = false) {
            const toast = document.getElementById('toast');
            toast.textContent = msg;
            toast.classList.remove('hidden', 'bg-red-600/90', 'bg-green-600/90');
            toast.classList.add(isError ? 'bg-red-600/90' : 'bg-green-600/90');
            setTimeout(() => toast.classList.add('hidden'), 3000);
        }

        async function fetchAllUsers() {
            const res = await fetch('api.php?action=get_all_users', { headers: { 'X-CSRF-TOKEN': csrfToken } });
            if (res.ok) {
                allUsers = await res.json();
                // Urutkan berdasarkan created_at descending (terbaru di atas)
                allUsers.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
                renderLatestUsers(); // <-- tambahan untuk 10 user terakhir
            }
        }
        function applyUserFilterAndPaginate() {
            if (!hasUserSearch) {
                renderEmptyUserMessage();
                return;
            }
            if (currentUserFilter.trim() === '') {
                filteredUsers = [...allUsers];
            } else {
                filteredUsers = allUsers.filter(u => u.username.toLowerCase().includes(currentUserFilter.toLowerCase()));
            }
            totalUserPages = Math.ceil(filteredUsers.length / usersPerPage);
            if (totalUserPages === 0) totalUserPages = 1;
            if (currentUserPage < 1) currentUserPage = 1;
            if (currentUserPage > totalUserPages) currentUserPage = totalUserPages;
            renderUserTable();
            renderUserPagination();
        }

        function renderEmptyUserMessage() {
            const container = document.getElementById('user-tickets-list');
            container.innerHTML = '<div class="text-center py-4 text-slate-400">🔍 Masukkan username dan klik Cari untuk menampilkan data.</div>';
            const paginationContainer = document.getElementById('user-pagination');
            if (paginationContainer) paginationContainer.innerHTML = '';
        }

        function renderUserTable() {
            const container = document.getElementById('user-tickets-list');
            if (filteredUsers.length === 0) {
                container.innerHTML = '<div class="text-center py-4 text-slate-400">Tidak ada user ditemukan dengan kata kunci tersebut.</div>';
                return;
            }
            const start = (currentUserPage - 1) * usersPerPage;
            const end = start + usersPerPage;
            const pageUsers = filteredUsers.slice(start, end);
            let html = '<div class="overflow-x-auto"><table class="w-full text-sm"><thead><th class="px-2 py-2">Username</th><th class="px-2 py-2">Tiket</th><th class="px-2 py-2">Poin</th><th class="px-2 py-2">Klaim Terakhir (WIB)</th><th class="px-2 py-2 whitespace-nowrap">Aksi Tiket</th><th class="px-2 py-2 whitespace-nowrap">Aksi Poin</th><th class="px-2 py-2 whitespace-nowrap">Ubah Password</th></tr></thead><tbody>';
            pageUsers.forEach(u => {
                const lastClaimFormatted = u.last_daily_claim ? formatWIB(u.last_daily_claim) : 'Belum pernah';
                html += `<tr class="border-b border-white/5 hover:bg-white/5">
                    <td class="px-2 py-2 font-medium">${escapeHtml(u.username)}</td>
                    <td class="px-2 py-2 font-mono font-bold text-center">${u.tickets}</td>
                    <td class="px-2 py-2 font-mono font-bold text-center">${u.points}</td>
                    <td class="px-2 py-2 text-slate-400 text-xs">${lastClaimFormatted}</td>
                    <td class="px-2 py-2 whitespace-nowrap">
                        <div class="flex gap-1 flex-wrap">
                            <button onclick="addTickets(${u.id}, 1)" class="bg-green-500/20 hover:bg-green-500/30 text-green-400 px-2 py-1 rounded text-[10px]">+1</button>
                            <button onclick="removeTickets(${u.id}, 1)" class="bg-red-500/20 hover:bg-red-500/30 text-red-400 px-2 py-1 rounded text-[10px]">-1</button>
                            <input type="number" id="amt-${u.id}" placeholder="jml" class="w-16 bg-white/5 border border-white/10 rounded px-1 py-1 text-xs text-center">
                            <button onclick="addTickets(${u.id}, document.getElementById('amt-${u.id}').value)" class="bg-amber-500 text-black px-2 py-1 rounded text-[10px]">+</button>
                            <button onclick="removeTickets(${u.id}, document.getElementById('amt-${u.id}').value)" class="bg-red-700 text-white px-2 py-1 rounded text-[10px]">-</button>
                        </div>
                      </td>
                    <td class="px-2 py-2 whitespace-nowrap">
                        <div class="flex gap-1 flex-wrap">
                            <button onclick="adjustPoints(${u.id}, 1)" class="bg-blue-500/20 hover:bg-blue-500/30 text-blue-400 px-2 py-1 rounded text-[10px]">+1</button>
                            <button onclick="adjustPoints(${u.id}, -1)" class="bg-orange-500/20 hover:bg-orange-500/30 text-orange-400 px-2 py-1 rounded text-[10px]">-1</button>
                            <input type="number" id="pts-${u.id}" placeholder="jml" class="w-16 bg-white/5 border border-white/10 rounded px-1 py-1 text-xs text-center">
                            <button onclick="adjustPoints(${u.id}, document.getElementById('pts-${u.id}').value)" class="bg-amber-500 text-black px-2 py-1 rounded text-[10px]">+</button>
                            <button onclick="adjustPoints(${u.id}, -document.getElementById('pts-${u.id}').value)" class="bg-red-700 text-white px-2 py-1 rounded text-[10px]">-</button>
                        </div>
                      </td>
                    <td class="px-2 py-2 whitespace-nowrap">
                        <button onclick="changeUserPassword(${u.id}, '${escapeHtml(u.username)}')" 
                            class="bg-purple-500/20 hover:bg-purple-500/30 text-purple-400 px-3 py-1 rounded text-[10px] font-black whitespace-nowrap">
                            🔑 Ubah Password
                        </button>
                      </td>
                    </tr>`;
            });
            html += '</tbody><tr></div>';
            container.innerHTML = html;
        }

        function renderUserPagination() {
            const container = document.getElementById('user-pagination');
            if (!container) return;
            if (!hasUserSearch || totalUserPages <= 1) {
                container.innerHTML = '';
                return;
            }
            let html = '<div class="flex justify-center gap-2 mt-4">';
            if (currentUserPage > 1) {
                html += `<button onclick="goToUserPage(${currentUserPage - 1})" class="px-3 py-1 rounded bg-white/5 hover:bg-white/10 text-white">Prev</button>`;
            }
            html += `<span class="px-3 py-1 text-slate-400">Halaman ${currentUserPage} dari ${totalUserPages}</span>`;
            if (currentUserPage < totalUserPages) {
                html += `<button onclick="goToUserPage(${currentUserPage + 1})" class="px-3 py-1 rounded bg-white/5 hover:bg-white/10 text-white">Next</button>`;
            }
            html += '</div>';
            container.innerHTML = html;
        }

        function goToUserPage(page) {
            currentUserPage = page;
            applyUserFilterAndPaginate();
        }

        async function addTickets(userId, amount) { if (!amount || amount <= 0) return; amount = parseInt(amount); const form = new FormData(); form.append('user_id', userId); form.append('amount', amount); const res = await fetch('api.php?action=add_tickets', { method: 'POST', body: form, headers: { 'X-CSRF-TOKEN': csrfToken } }); const data = await res.json(); if (data.status === 'success') { showToast('Tiket ditambahkan'); await fetchAllUsers(); if (hasUserSearch) applyUserFilterAndPaginate(); if (document.getElementById('tab-leaderboard').classList.contains('hidden') === false) loadLeaderboardData(); } else showToast(data.error || 'Gagal', true); }
        async function removeTickets(userId, amount) { if (!amount || amount <= 0) return; amount = parseInt(amount); const form = new FormData(); form.append('user_id', userId); form.append('amount', amount); const res = await fetch('api.php?action=remove_tickets', { method: 'POST', body: form, headers: { 'X-CSRF-TOKEN': csrfToken } }); const data = await res.json(); if (data.status === 'success') { showToast('Tiket dikurangi'); await fetchAllUsers(); if (hasUserSearch) applyUserFilterAndPaginate(); if (document.getElementById('tab-leaderboard').classList.contains('hidden') === false) loadLeaderboardData(); } else showToast(data.error || 'Gagal', true); }

        async function adjustPoints(userId, amount) {
            if (!amount || amount == 0) return;
            amount = parseInt(amount);
            const form = new FormData();
            form.append('user_id', userId);
            form.append('points', amount);
            const res = await fetch('api.php?action=adjust_points', { method: 'POST', body: form, headers: { 'X-CSRF-TOKEN': csrfToken } });
            const data = await res.json();
            if (data.status === 'success') {
                showToast('Poin diubah');
                await fetchAllUsers();
                if (hasUserSearch) applyUserFilterAndPaginate();
                if (document.getElementById('tab-leaderboard').classList.contains('hidden') === false) loadLeaderboardData();
            } else {
                showToast(data.error || 'Gagal mengubah poin', true);
            }
        }

        async function loadAdminData() {
            const res = await fetch('api.php?action=get_admin_data');
            if (!res.ok) return;
            const data = await res.json();
            allTeams = data.teams;
            allGroups = data.groups;
            groupMatches = data.group_matches;
            knockoutMatches = data.knockout_matches;
            populateGroupSelect();
            populateKnockoutSelect();
        }

        function populateGroupSelect() {
            const select = document.getElementById('admin-group-select');
            if (!select) return;
            let options = '<option value="">-- Pilih Pertandingan Grup --</option>';
            groupMatches.forEach(m => {
                const dateStr = m.match_date ? new Date(m.match_date).toLocaleString('id-ID') : 'TBD';
                const statusText = m.is_finished ? '✓ Selesai' : '○ Belum';
                options += `<option value="${m.id}">M${m.id} | Group ${m.group_name} | ${dateStr} | ${escapeHtml(m.team1_name)} vs ${escapeHtml(m.team2_name)} | ${statusText}</option>`;
            });
            select.innerHTML = options;
        }

        function populateKnockoutSelect() {
            const select = document.getElementById('admin-knockout-select');
            if (!select) return;
            const stageOrder = ['R32', 'R16', 'QF', 'SF', '3rd', 'F'];
            const stageNames = { R32: 'Round of 32', R16: 'Round of 16', QF: 'Quarter Final', SF: 'Semi Final', '3rd': 'Third Place', F: 'Final' };
            let groups = { R32: [], R16: [], QF: [], SF: [], '3rd': [], F: [] };
            knockoutMatches.forEach(m => {
                let dateStr = m.match_date ? new Date(m.match_date).toLocaleString('id-ID') : 'TBD';
                let team1 = m.team1_name || m.team1_code || '?';
                let team2 = m.team2_name || m.team2_code || '?';
                const statusText = m.is_finished ? '✓ Selesai' : '○ Belum';
                groups[m.stage].push(`<option value="${m.id}">M${m.id} | ${dateStr} | ${escapeHtml(team1)} vs ${escapeHtml(team2)} | ${statusText}</option>`);
            });
            let html = '<option value="">-- Pilih Pertandingan Knockout --</option>';
            for (let stage of stageOrder) {
                if (groups[stage].length) html += `<optgroup label="${stageNames[stage]}">${groups[stage].join('')}</optgroup>`;
            }
            select.innerHTML = html;
        }

        document.getElementById('load-group-match')?.addEventListener('click', () => {
            const id = document.getElementById('admin-group-select').value;
            if (!id) return;
            loadGroupMatchForm(id);
        });
        document.getElementById('load-knockout-match')?.addEventListener('click', () => {
            const id = document.getElementById('admin-knockout-select').value;
            if (!id) return;
            loadKnockoutMatchForm(id);
        });

        async function loadGroupMatchForm(matchId) {
            const match = groupMatches.find(m => m.id == matchId);
            if (!match) return;
            const formDiv = document.getElementById('group-edit-form');
            const statusClass = match.is_finished ? 'status-selesai' : 'status-belum';
            const statusIcon = match.is_finished ? '✅' : '⏳';
            const statusText = match.is_finished ? 'Pertandingan Telah Selesai' : 'Pertandingan Belum Dimulai';
            formDiv.innerHTML = `
                <div class="mb-6 flex flex-wrap items-center justify-between gap-4 p-4 bg-white/5 rounded-2xl border border-white/10">
                    <div class="flex items-center gap-4">
                        <span class="text-sm font-black text-amber-500 uppercase tracking-wider">STATUS PERTANDINGAN</span>
                        <div class="match-status-badge ${statusClass}">
                            ${statusIcon} ${statusText}
                        </div>
                    </div>
                    <div class="flex items-center gap-3">
                        <label class="text-sm font-black text-white uppercase tracking-wider">Tandai Selesai</label>
                        <input type="checkbox" id="edit_grp_finished" ${match.is_finished ? 'checked' : ''} class="w-6 h-6 rounded border-amber-500 bg-white/5 focus:ring-amber-500">
                    </div>
                </div>
                <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                    <div><label>Tim 1</label><select id="edit_grp_t1" class="w-full bg-white/5 border rounded-xl p-2">${allTeams.map(t => `<option value="${t.id}" ${match.team1_id == t.id ? 'selected' : ''}>${escapeHtml(t.name)}</option>`).join('')}</select></div>
                    <div><label>Tim 2</label><select id="edit_grp_t2" class="w-full bg-white/5 border rounded-xl p-2">${allTeams.map(t => `<option value="${t.id}" ${match.team2_id == t.id ? 'selected' : ''}>${escapeHtml(t.name)}</option>`).join('')}</select></div>
                    <div><label>Tanggal</label><input type="datetime-local" id="edit_grp_date" value="${formatLocalDateTime(match.match_date)}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Skor Tim 1</label><input type="number" id="edit_grp_s1" value="${match.team1_score}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Skor Tim 2</label><input type="number" id="edit_grp_s2" value="${match.team2_score}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Total Gol Aktual</label><input type="number" id="edit_grp_total_goals" value="${match.total_goals_actual ?? ''}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Corner Aktual</label><input type="number" id="edit_grp_corners" value="${match.corners_actual ?? ''}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Kartu Kuning Aktual</label><input type="number" id="edit_grp_yellow" value="${match.yellow_cards_actual ?? ''}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Kartu Merah Aktual</label><input type="number" id="edit_grp_red" value="${match.red_cards_actual ?? ''}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Offside Aktual</label><input type="number" id="edit_grp_offsides" value="${match.offsides_actual ?? ''}" class="w-full bg-white/5 rounded-xl p-2"></div>
                </div>
                <div class="flex justify-end gap-2 mt-4">
                    <button onclick="updateGroupMatch(${match.id})" class="bg-amber-500 text-black px-4 py-2 rounded-xl text-xs font-black">Simpan</button>
                    <button onclick="deleteGroupMatch(${match.id})" class="bg-red-500/80 text-white px-4 py-2 rounded-xl text-xs font-black">Hapus</button>
                </div>
            `;
            formDiv.classList.remove('hidden');
            const chk = document.getElementById('edit_grp_finished');
            const badgeDiv = document.querySelector('#group-edit-form .match-status-badge');
            if (chk && badgeDiv) {
                chk.addEventListener('change', function () {
                    if (this.checked) {
                        badgeDiv.className = 'match-status-badge status-selesai';
                        badgeDiv.innerHTML = '✅ Pertandingan Telah Selesai';
                    } else {
                        badgeDiv.className = 'match-status-badge status-belum';
                        badgeDiv.innerHTML = '⏳ Pertandingan Belum Dimulai';
                    }
                });
            }
        }

        async function updateGroupMatch(id) {
            const t1 = document.getElementById('edit_grp_t1').value;
            const t2 = document.getElementById('edit_grp_t2').value;
            const s1 = parseInt(document.getElementById('edit_grp_s1').value) || 0;
            const s2 = parseInt(document.getElementById('edit_grp_s2').value) || 0;
            const date = document.getElementById('edit_grp_date').value;
            const finished = document.getElementById('edit_grp_finished').checked ? 1 : 0;
            const totalGoals = document.getElementById('edit_grp_total_goals').value !== '' ? parseInt(document.getElementById('edit_grp_total_goals').value) : null;
            const corners = document.getElementById('edit_grp_corners').value !== '' ? parseInt(document.getElementById('edit_grp_corners').value) : null;
            const yellow = document.getElementById('edit_grp_yellow').value !== '' ? parseInt(document.getElementById('edit_grp_yellow').value) : null;
            const red = document.getElementById('edit_grp_red').value !== '' ? parseInt(document.getElementById('edit_grp_red').value) : null;
            const offsides = document.getElementById('edit_grp_offsides').value !== '' ? parseInt(document.getElementById('edit_grp_offsides').value) : null;
            const form = new FormData();
            form.append('id', id); form.append('team1_id', t1); form.append('team2_id', t2);
            form.append('team1_score', s1); form.append('team2_score', s2);
            form.append('match_date', date); form.append('is_finished', finished);
            if (totalGoals !== null) form.append('total_goals_actual', totalGoals);
            if (corners !== null) form.append('corners_actual', corners);
            if (yellow !== null) form.append('yellow_cards_actual', yellow);
            if (red !== null) form.append('red_cards_actual', red);
            if (offsides !== null) form.append('offsides_actual', offsides);
            const res = await fetch('api.php?action=update_group_match', { method: 'POST', body: form, headers: { 'X-CSRF-TOKEN': csrfToken } });
            if (res.ok) { showToast('Pertandingan grup diperbarui'); loadAdminData(); } else showToast('Gagal update', true);
        }

        async function deleteGroupMatch(id) {
            if (!confirm('Hapus pertandingan ini?')) return;
            const form = new FormData(); form.append('id', id);
            const res = await fetch('api.php?action=delete_group_match', { method: 'POST', body: form, headers: { 'X-CSRF-TOKEN': csrfToken } });
            if (res.ok) { showToast('Pertandingan dihapus'); loadAdminData(); document.getElementById('group-edit-form').classList.add('hidden'); } else showToast('Gagal hapus', true);
        }

        document.getElementById('create-group-btn')?.addEventListener('click', () => {
            const formDiv = document.getElementById('group-create-form');
            formDiv.innerHTML = `
                <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
                    <div><label>Grup</label><select id="new_gid" class="w-full bg-white/5 border rounded-xl p-2">${allGroups.map(g => `<option value="${g.id}">Group ${g.name}</option>`).join('')}</select></div>
                    <div><label>Tim 1</label><select id="new_t1" class="w-full bg-white/5 border rounded-xl p-2">${allTeams.map(t => `<option value="${t.id}">${escapeHtml(t.name)}</option>`).join('')}</select></div>
                    <div><label>Tim 2</label><select id="new_t2" class="w-full bg-white/5 border rounded-xl p-2">${allTeams.map(t => `<option value="${t.id}">${escapeHtml(t.name)}</option>`).join('')}</select></div>
                    <div><label>Tanggal</label><input type="datetime-local" id="new_date" class="w-full bg-white/5 rounded-xl p-2"></div>
                </div>
                <div class="flex justify-end mt-4"><button onclick="createGroupMatch()" class="bg-amber-500 text-black px-4 py-2 rounded-xl text-xs font-black">Buat</button></div>
            `;
            formDiv.classList.remove('hidden');
        });

        async function createGroupMatch() {
            const gid = document.getElementById('new_gid').value;
            const t1 = document.getElementById('new_t1').value;
            const t2 = document.getElementById('new_t2').value;
            const date = document.getElementById('new_date').value;
            const form = new FormData();
            form.append('group_id', gid); form.append('team1_id', t1); form.append('team2_id', t2); form.append('match_date', date);
            const res = await fetch('api.php?action=create_group_match', { method: 'POST', body: form, headers: { 'X-CSRF-TOKEN': csrfToken } });
            if (res.ok) { showToast('Pertandingan dibuat'); loadAdminData(); document.getElementById('group-create-form').classList.add('hidden'); } else showToast('Gagal buat', true);
        }

        async function loadKnockoutMatchForm(matchId) {
            const match = knockoutMatches.find(m => m.id == matchId);
            if (!match) return;
            const formDiv = document.getElementById('knockout-edit-form');
            const teams = allTeams;
            const team1Name = match.team1_name || match.team1_code || '';
            const team2Name = match.team2_name || match.team2_code || '';
            const statusClass = match.is_finished ? 'status-selesai' : 'status-belum';
            const statusIcon = match.is_finished ? '✅' : '⏳';
            const statusText = match.is_finished ? 'Pertandingan Telah Selesai' : 'Pertandingan Belum Dimulai';
            formDiv.innerHTML = `
                <div class="mb-6 flex flex-wrap items-center justify-between gap-4 p-4 bg-white/5 rounded-2xl border border-white/10">
                    <div class="flex items-center gap-4">
                        <span class="text-sm font-black text-amber-500 uppercase tracking-wider">STATUS PERTANDINGAN</span>
                        <div class="match-status-badge ${statusClass}">
                            ${statusIcon} ${statusText}
                        </div>
                    </div>
                    <div class="flex items-center gap-3">
                        <label class="text-sm font-black text-white uppercase tracking-wider">Tandai Selesai</label>
                        <input type="checkbox" id="edit_ko_finished" ${match.is_finished ? 'checked' : ''} class="w-6 h-6 rounded border-amber-500 bg-white/5 focus:ring-amber-500">
                    </div>
                </div>
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div><label>Tim 1</label><select id="edit_ko_t1" class="w-full bg-white/5 border rounded-xl p-2"><option value="">Kosongkan</option>${teams.map(t => `<option value="${t.id}" ${match.team1_id == t.id ? 'selected' : ''}>${escapeHtml(t.name)}</option>`).join('')}</select></div>
                    <div><label>Tim 2</label><select id="edit_ko_t2" class="w-full bg-white/5 border rounded-xl p-2"><option value="">Kosongkan</option>${teams.map(t => `<option value="${t.id}" ${match.team2_id == t.id ? 'selected' : ''}>${escapeHtml(t.name)}</option>`).join('')}</select></div>
                    <div><label>Skor Akhir</label><input type="number" id="edit_ko_s1" value="${match.team1_score}" class="w-full bg-white/5 rounded-xl p-2 text-center"></div>
                    <div><label>Skor Akhir</label><input type="number" id="edit_ko_s2" value="${match.team2_score}" class="w-full bg-white/5 rounded-xl p-2 text-center"></div>
                    <div><label>Skor Normal (2x45)</label><input type="number" id="edit_ko_s1_normal" value="${match.team1_score_normal ?? match.team1_score}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Skor Normal (2x45)</label><input type="number" id="edit_ko_s2_normal" value="${match.team2_score_normal ?? match.team2_score}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Tanggal</label><input type="datetime-local" id="edit_ko_date" value="${formatLocalDateTime(match.match_date)}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Pemenang (jika seri)</label><select id="edit_ko_winner" class="w-full bg-white/5 border rounded-xl p-2"><option value="">-- Tidak ditentukan --</option><option value="${match.team1_id}" ${match.winner_id == match.team1_id ? 'selected' : ''}>${team1Name || 'Tim 1'}</option><option value="${match.team2_id}" ${match.winner_id == match.team2_id ? 'selected' : ''}>${team2Name || 'Tim 2'}</option></select></div>
                    <div><label>Perpanjangan Waktu</label><select id="edit_ko_extension" class="w-full bg-white/5 border rounded-xl p-2"><option value="none" ${match.match_extension == 'none' ? 'selected' : ''}>90 menit</option><option value="et" ${match.match_extension == 'et' ? 'selected' : ''}>Extra Time</option><option value="pen" ${match.match_extension == 'pen' ? 'selected' : ''}>Penalti</option></select></div>
                    <div><label>Total Gol Aktual</label><input type="number" id="edit_ko_total_goals" value="${match.total_goals_actual ?? ''}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Corner Aktual</label><input type="number" id="edit_ko_corners" value="${match.corners_actual ?? ''}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Kartu Kuning Aktual</label><input type="number" id="edit_ko_yellow" value="${match.yellow_cards_actual ?? ''}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Kartu Merah Aktual</label><input type="number" id="edit_ko_red" value="${match.red_cards_actual ?? ''}" class="w-full bg-white/5 rounded-xl p-2"></div>
                    <div><label>Offside Aktual</label><input type="number" id="edit_ko_offsides" value="${match.offsides_actual ?? ''}" class="w-full bg-white/5 rounded-xl p-2"></div>
                </div>
                <div class="flex justify-end mt-4"><button onclick="updateKnockoutMatch(${match.id})" class="bg-amber-500 text-black px-4 py-2 rounded-xl text-xs font-black">Simpan</button></div>
            `;
            formDiv.classList.remove('hidden');
            const chk = document.getElementById('edit_ko_finished');
            const badgeDiv = document.querySelector('#knockout-edit-form .match-status-badge');
            if (chk && badgeDiv) {
                chk.addEventListener('change', function () {
                    if (this.checked) {
                        badgeDiv.className = 'match-status-badge status-selesai';
                        badgeDiv.innerHTML = '✅ Pertandingan Telah Selesai';
                    } else {
                        badgeDiv.className = 'match-status-badge status-belum';
                        badgeDiv.innerHTML = '⏳ Pertandingan Belum Dimulai';
                    }
                });
            }
        }

        async function updateKnockoutMatch(id) {
            const t1 = document.getElementById('edit_ko_t1').value || null;
            const t2 = document.getElementById('edit_ko_t2').value || null;
            const s1 = parseInt(document.getElementById('edit_ko_s1').value) || 0;
            const s2 = parseInt(document.getElementById('edit_ko_s2').value) || 0;
            const s1n = document.getElementById('edit_ko_s1_normal').value !== '' ? parseInt(document.getElementById('edit_ko_s1_normal').value) : null;
            const s2n = document.getElementById('edit_ko_s2_normal').value !== '' ? parseInt(document.getElementById('edit_ko_s2_normal').value) : null;
            const date = document.getElementById('edit_ko_date').value;
            const finished = document.getElementById('edit_ko_finished').checked ? 1 : 0;
            const winner = document.getElementById('edit_ko_winner').value || null;
            const extension = document.getElementById('edit_ko_extension').value;
            const totalGoals = document.getElementById('edit_ko_total_goals').value !== '' ? parseInt(document.getElementById('edit_ko_total_goals').value) : null;
            const corners = document.getElementById('edit_ko_corners').value !== '' ? parseInt(document.getElementById('edit_ko_corners').value) : null;
            const yellow = document.getElementById('edit_ko_yellow').value !== '' ? parseInt(document.getElementById('edit_ko_yellow').value) : null;
            const red = document.getElementById('edit_ko_red').value !== '' ? parseInt(document.getElementById('edit_ko_red').value) : null;
            const offsides = document.getElementById('edit_ko_offsides').value !== '' ? parseInt(document.getElementById('edit_ko_offsides').value) : null;
            const form = new FormData();
            form.append('id', id); form.append('team1_id', t1); form.append('team2_id', t2);
            form.append('team1_score', s1); form.append('team2_score', s2);
            if (s1n !== null) form.append('team1_score_normal', s1n);
            if (s2n !== null) form.append('team2_score_normal', s2n);
            form.append('match_date', date); form.append('is_finished', finished);
            if (winner) form.append('winner_id', winner);
            form.append('match_extension', extension);
            if (totalGoals !== null) form.append('total_goals_actual', totalGoals);
            if (corners !== null) form.append('corners_actual', corners);
            if (yellow !== null) form.append('yellow_cards_actual', yellow);
            if (red !== null) form.append('red_cards_actual', red);
            if (offsides !== null) form.append('offsides_actual', offsides);
            const res = await fetch('api.php?action=update_knockout', { method: 'POST', body: form, headers: { 'X-CSRF-TOKEN': csrfToken } });
            if (res.ok) { showToast('Pertandingan knockout diperbarui'); loadAdminData(); } else showToast('Gagal update', true);
        }

        async function loadTicketCodes(page = 1) {
            const container = document.getElementById('ticket-codes-list');
            container.innerHTML = '<div class="text-center py-4"><div class="animate-spin h-6 w-6 border-b-2 border-amber-500 inline-block"></div></div>';
            try {
                const res = await fetch(`api.php?action=get_ticket_codes&page=${page}&limit=${TICKET_LIMIT}`, { headers: { 'X-CSRF-TOKEN': csrfToken } });
                const data = await res.json();
                if (!data.codes.length) { container.innerHTML = '<div class="text-center py-4 text-slate-400">Belum ada kode tiket.</div>'; return; }
                let html = '<div class="overflow-x-auto"><table class="w-full text-sm"><thead><tr><th class="px-2 py-2">Kode</th><th class="px-2 py-2">Tiket</th><th class="px-2 py-2">Maks</th><th class="px-2 py-2">Terpakai</th><th class="px-2 py-2">Kadaluarsa</th><th class="px-2 py-2">Status</th><th class="px-2 py-2">Dibuat</th></tr></thead><tbody>';
                for (const c of data.codes) {
                    let status = '', cls = '';
                    const expired = c.expires_at && new Date(c.expires_at) < new Date();
                    const full = c.used_count >= c.max_uses;
                    if (expired) { status = 'Kadaluarsa'; cls = 'text-red-400'; }
                    else if (full) { status = 'Kuota Habis'; cls = 'text-yellow-400'; }
                    else { status = 'Tersedia'; cls = 'text-green-400'; }
                    html += `<tr>
                        <td class="px-2 py-2 font-mono">${escapeHtml(c.code)}</td>
                        <td class="px-2 py-2 text-center">${c.ticket_amount}</td>
                        <td class="px-2 py-2 text-center">${c.max_uses}</td>
                        <td class="px-2 py-2 text-center">${c.used_count}</td>
                        <td class="px-2 py-2 text-center">${c.expires_at ? new Date(c.expires_at).toLocaleString('id-ID') : '-'}</td>
                        <td class="px-2 py-2 text-center ${cls}">${status}</td>
                        <td class="px-2 py-2 text-center">${escapeHtml(c.created_by_name)}</td>
                    </tr>`;
                }
                html += '</tbody></table></div>';
                if (data.total_pages > 1) {
                    html += `<div class="flex justify-center gap-2 mt-4"><button onclick="loadTicketCodes(${page - 1})" class="px-3 py-1 rounded bg-white/5" ${page <= 1 ? 'disabled' : ''}>Prev</button><span>Halaman ${page} dari ${data.total_pages}</span><button onclick="loadTicketCodes(${page + 1})" class="px-3 py-1 rounded bg-white/5" ${page >= data.total_pages ? 'disabled' : ''}>Next</button></div>`;
                }
                container.innerHTML = html;
            } catch (e) { container.innerHTML = '<div class="text-center py-4 text-red-400">Gagal memuat</div>'; }
        }

        document.getElementById('generate-ticket-code-btn')?.addEventListener('click', async () => {
            const amount = document.getElementById('admin-ticket-amount').value;
            const maxUses = document.getElementById('admin-max-uses').value || 1;
            const expires = document.getElementById('admin-expires-at').value;
            if (!amount || amount <= 0) { showToast('Jumlah tiket harus >0', true); return; }
            const form = new FormData();
            form.append('ticket_amount', amount); form.append('max_uses', maxUses);
            if (expires) form.append('expires_at', expires);
            const res = await fetch('api.php?action=generate_ticket_code', { method: 'POST', body: form, headers: { 'X-CSRF-TOKEN': csrfToken } });
            const data = await res.json();
            if (data.status === 'success') { showToast(`Kode: ${data.code}`); loadTicketCodes(); }
            else showToast(data.error || 'Gagal', true);
        });

        async function loadPointRedeemsLog(page = 1) {
            const container = document.getElementById('point-redeems-log');
            container.innerHTML = '<div class="text-center py-4"><div class="animate-spin h-6 w-6 border-b-2 border-amber-500 inline-block"></div></div>';
            try {
                const res = await fetch(`api.php?action=get_point_redeems_log&page=${page}&limit=${POINT_LIMIT}`, { headers: { 'X-CSRF-TOKEN': csrfToken } });
                const data = await res.json();
                if (!data.logs.length) { container.innerHTML = '<div class="text-center py-4 text-slate-400">Belum ada data penukaran poin.</div>'; return; }
                let html = '<div class="overflow-x-auto"><table class="w-full text-sm"><thead><tr><th class="px-2 py-2">Username</th><th class="px-2 py-2">No HP</th><th class="px-2 py-2">Hadiah</th><th class="px-2 py-2 text-center">Poin</th><th class="px-2 py-2 text-center whitespace-nowrap">Waktu</th><th class="px-2 py-2 text-center">Status</th></tr></thead><tbody>';
                for (const log of data.logs) {
                    const rewardName = log.reward_name ? escapeHtml(log.reward_name) : (log.reward_id ? `Reward ID ${log.reward_id}` : '-');
                    const statusClass = log.status === 'approved' ? 'text-green-400' : (log.status === 'rejected' ? 'text-red-400' : 'text-yellow-400');
                    html += `<tr class="border-b border-white/5 hover:bg-white/5">
                        <td class="px-2 py-2 font-medium">${escapeHtml(log.username || '-')}</td>
                        <td class="px-2 py-2">${escapeHtml(log.phone_number || '-')}</td>
                        <td class="px-2 py-2">${rewardName}</td>
                        <td class="px-2 py-2 text-center font-mono">${log.points_spent}</td>
                        <td class="px-2 py-2 text-center text-slate-400 whitespace-nowrap">${new Date(log.redeemed_at).toLocaleString('id-ID')}</td>
                        <td class="px-2 py-2 text-center ${statusClass} font-semibold">${log.status}</td>
                    </tr>`;
                }
                html += '</tbody></table></div>';
                if (data.total_pages > 1) {
                    html += `<div class="flex justify-center gap-2 mt-4"><button onclick="loadPointRedeemsLog(${page - 1})" class="px-3 py-1 rounded bg-white/5" ${page <= 1 ? 'disabled' : ''}>Prev</button><span>Halaman ${page} dari ${data.total_pages}</span><button onclick="loadPointRedeemsLog(${page + 1})" class="px-3 py-1 rounded bg-white/5" ${page >= data.total_pages ? 'disabled' : ''}>Next</button></div>`;
                }
                container.innerHTML = html;
            } catch (e) { container.innerHTML = '<div class="text-center py-4 text-red-400">Gagal memuat</div>'; }
        }

        document.getElementById('refresh-point-logs')?.addEventListener('click', () => loadPointRedeemsLog(1));

        function renderLatestUsers() {
            const container = document.getElementById('latest-users-list');
            if (!allUsers.length) {
                container.innerHTML = '<div class="text-center py-4 text-slate-400">Belum ada data user.</div>';
                return;
            }
            // Urutkan berdasarkan created_at descending (terbaru di atas)
            const sorted = [...allUsers].sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
            const latest10 = sorted.slice(0, 10);
            let html = '<div class="overflow-x-auto"><table class="w-full text-sm"><thead><th class="px-2 py-2">Username</th><th class="px-2 py-2">Bergabung Pada (WIB)</th><th class="px-2 py-2">Tiket</th><th class="px-2 py-2">Poin</th></tr></thead><tbody>';
            latest10.forEach(user => {
                // Konversi created_at dari UTC ke WIB
                const joinedDate = user.created_at ? formatWIB(user.created_at) : '-';
                html += `<tr class="border-b border-white/5">
            <td class="px-2 py-2 font-medium">${escapeHtml(user.username)}</td>
            <td class="px-2 py-2 text-xs text-slate-400">${joinedDate}</td>
            <td class="px-2 py-2 text-center">${user.tickets}</td>
            <td class="px-2 py-2 text-center">${user.points}</td>
        </tr>`;
            });
            html += '</tbody></table></div>';
            container.innerHTML = html;
        }

        function renderLeaderboardLive() {
            const container = document.getElementById('leaderboard-list');
            if (!allUsers.length) {
                container.innerHTML = '<div class="text-center py-4 text-slate-400">Memuat leaderboard...</div>';
                return;
            }
            const sorted = [...allUsers].sort((a, b) => {
                if (a.points !== b.points) return b.points - a.points;
                return a.username.localeCompare(b.username);
            });
            const top10 = sorted.slice(0, 10);
            if (top10.length === 0) {
                container.innerHTML = '<div class="text-center py-4 text-slate-400">Belum ada data leaderboard.</div>';
                return;
            }
            let html = '<div class="overflow-x-auto"><table class="w-full text-sm"><thead><tr><th class="px-2 py-2">Rank</th><th class="px-2 py-2">Username</th><th class="px-2 py-2">Poin</th><th class="px-2 py-2">Aksi Adjust Poin</th></tr></thead><tbody>';
            top10.forEach((user, idx) => {
                const rank = idx + 1;
                html += `<tr class="border-b border-white/5 hover:bg-white/5">
                    <td class="px-2 py-2 font-mono font-bold">#${rank}</td>
                    <td class="px-2 py-2 font-bold">${escapeHtml(user.username)}</td>
                    <td class="px-2 py-2 font-mono font-bold">${user.points}</td>
                    <td class="px-2 py-2 whitespace-nowrap">
                        <div class="flex gap-1 flex-wrap">
                            <button onclick="adjustPointsFromLeaderboard('${escapeHtml(user.username)}', 1)" class="bg-blue-500/20 hover:bg-blue-500/30 text-blue-400 px-2 py-1 rounded text-[10px]">+1</button>
                            <button onclick="adjustPointsFromLeaderboard('${escapeHtml(user.username)}', -1)" class="bg-orange-500/20 hover:bg-orange-500/30 text-orange-400 px-2 py-1 rounded text-[10px]">-1</button>
                            <input type="number" id="ld-pts-${rank}" placeholder="jml" class="w-20 bg-white/5 border border-white/10 rounded px-1 py-1 text-xs">
                            <button onclick="adjustPointsFromLeaderboard('${escapeHtml(user.username)}', document.getElementById('ld-pts-${rank}').value)" class="bg-amber-500 text-black px-2 py-1 rounded text-[10px]">+</button>
                            <button onclick="adjustPointsFromLeaderboard('${escapeHtml(user.username)}', -document.getElementById('ld-pts-${rank}').value)" class="bg-red-700 text-white px-2 py-1 rounded text-[10px]">-</button>
                        </div>
                      </td>
                </tr>`;
            });
            html += '</tbody></table></div>';
            container.innerHTML = html;
        }

        async function adjustPointsFromLeaderboard(username, amount) {
            if (!amount || amount == 0) return;
            amount = parseInt(amount);
            const user = allUsers.find(u => u.username === username);
            if (!user) {
                showToast('User tidak ditemukan', true);
                return;
            }
            await adjustPoints(user.id, amount);
            await loadLeaderboardData();
        }

        async function forceLeaderboardSnapshot() {
            const btn = document.getElementById('force-snapshot-btn');
            if (!btn) return;
            const originalText = btn.innerHTML;
            btn.innerHTML = '<div class="animate-spin h-4 w-4 border-2 border-amber-500 rounded-full border-t-transparent inline-block mr-2"></div> Loading...';
            btn.disabled = true;
            try {
                const res = await fetch('api.php?action=admin_force_leaderboard', {
                    method: 'POST',
                    headers: { 'X-CSRF-TOKEN': csrfToken }
                });
                const data = await res.json();
                if (data.status === 'success') {
                    showToast('Snapshot leaderboard berhasil diperbarui!', false);
                    await loadLeaderboardData();
                } else {
                    showToast(data.error || 'Gagal update snapshot', true);
                }
            } catch (err) {
                showToast('Terjadi kesalahan jaringan', true);
            } finally {
                btn.innerHTML = originalText;
                btn.disabled = false;
            }
        }

        async function deleteAllSnapshots() {
            if (!confirm('⚠️ PERINGATAN: Semua data snapshot leaderboard akan dihapus secara permanen. Lanjutkan?')) {
                return;
            }
            const btn = document.getElementById('delete-snapshots-btn');
            if (!btn) return;
            const originalText = btn.innerHTML;
            btn.innerHTML = '<div class="animate-spin h-4 w-4 border-2 border-red-500 rounded-full border-t-transparent inline-block mr-2"></div> Menghapus...';
            btn.disabled = true;
            try {
                const res = await fetch('api.php?action=admin_delete_snapshots', {
                    method: 'POST',
                    headers: { 'X-CSRF-TOKEN': csrfToken }
                });
                const data = await res.json();
                if (data.status === 'success') {
                    showToast('Semua snapshot leaderboard berhasil dihapus!', false);
                    await loadLeaderboardData();
                    const container = document.getElementById('leaderboard-list');
                    if (container) {
                        container.innerHTML = '<div class="text-center py-4 text-slate-400">Belum ada data snapshot. Klik "Update Snapshot Sekarang" untuk membuat snapshot baru.</div>';
                    }
                } else {
                    showToast(data.error || 'Gagal menghapus snapshot', true);
                }
            } catch (err) {
                showToast('Terjadi kesalahan jaringan', true);
            } finally {
                btn.innerHTML = originalText;
                btn.disabled = false;
            }
        }
        // ========== MANAJEMEN HADIAH (REWARDS) UNTUK ADMIN ==========
        async function loadRewardsForAdmin() {
            const container = document.getElementById('rewards-list-container');
            if (!container) return;
            container.innerHTML = '<div class="text-center py-4 text-slate-400"><div class="animate-spin h-6 w-6 border-b-2 border-amber-500 inline-block"></div> Memuat...</div>';
            try {
                const res = await fetch('api.php?action=admin_get_rewards', {
                    headers: { 'X-CSRF-TOKEN': csrfToken }
                });
                if (!res.ok) throw new Error('Gagal memuat data');
                const rewards = await res.json();
                if (rewards.length === 0) {
                    container.innerHTML = '<div class="text-center py-4 text-slate-400">Belum ada hadiah. Tambahkan hadiah melalui database atau API.</div>';
                    return;
                }
                let html = `<div class="overflow-x-auto"><table class="w-full text-sm"><thead><tr>
            <th class="px-2 py-2">ID</th>
            <th class="px-2 py-2">Nama Hadiah</th>
            <th class="px-2 py-2">Deskripsi</th>
            <th class="px-2 py-2">Poin</th>
            <th class="px-2 py-2">Stok</th>
            <th class="px-2 py-2">Status</th>
            <th class="px-2 py-2">Aksi Stok</th>
        </tr></thead><tbody>`;
                for (const reward of rewards) {
                    const statusClass = reward.is_active ? 'text-green-400' : 'text-red-400';
                    const statusText = reward.is_active ? 'Aktif' : 'Nonaktif';
                    html += `<tr class="border-b border-white/5 hover:bg-white/5">
                <td class="px-2 py-2">${reward.id}</td>
                <td class="px-2 py-2 font-bold">${escapeHtml(reward.name)}</td>
                <td class="px-2 py-2 max-w-xs truncate">${escapeHtml(reward.description || '')}</td>
                <td class="px-2 py-2 text-center">${reward.points_required}</td>
                <td class="px-2 py-2 text-center font-mono font-bold" id="stock-${reward.id}">${reward.stock}</td>
                <td class="px-2 py-2 text-center ${statusClass}">${statusText}</td>
                <td class="px-2 py-2 whitespace-nowrap">
                    <div class="flex gap-1 flex-wrap">
                        <button onclick="adjustStock(${reward.id}, 1)" class="bg-green-500/20 hover:bg-green-500/30 text-green-400 px-2 py-1 rounded text-[10px]">+1</button>
                        <button onclick="adjustStock(${reward.id}, -1)" class="bg-red-500/20 hover:bg-red-500/30 text-red-400 px-2 py-1 rounded text-[10px]">-1</button>
                        <input type="number" id="stock-amt-${reward.id}" placeholder="jml" class="w-16 bg-white/5 border border-white/10 rounded px-1 py-1 text-xs text-center">
                        <button onclick="adjustStock(${reward.id}, document.getElementById('stock-amt-${reward.id}').value)" class="bg-amber-500 text-black px-2 py-1 rounded text-[10px]">Set</button>
                    </div>
                </td>
            </tr>`;
                }
                html += `</tbody></table></div>`;
                container.innerHTML = html;
            } catch (err) {
                console.error(err);
                container.innerHTML = '<div class="text-center py-4 text-red-400">Gagal memuat data hadiah.</div>';
            }
        }

        async function adjustStock(rewardId, adjustment) {
            if (adjustment === '' || adjustment === null) return;
            let adjValue = parseInt(adjustment);
            if (isNaN(adjValue)) return;
            try {
                const formData = new FormData();
                formData.append('reward_id', rewardId);
                formData.append('adjustment', adjValue);
                const res = await fetch('api.php?action=admin_update_reward_stock', {
                    method: 'POST',
                    body: formData,
                    headers: { 'X-CSRF-TOKEN': csrfToken }
                });
                const data = await res.json();
                if (data.status === 'success') {
                    showToast(`Stok hadiah berhasil diubah. Stok baru: ${data.new_stock}`, false);
                    const stockSpan = document.getElementById(`stock-${rewardId}`);
                    if (stockSpan) stockSpan.innerText = data.new_stock;
                } else {
                    showToast(data.error || 'Gagal mengubah stok', true);
                }
            } catch (err) {
                showToast('Terjadi kesalahan jaringan', true);
            }
        }

        async function loadLeaderboardData() {
            await fetchAllUsers();
            renderLeaderboardLive();
        }

        function escapeHtml(str) { if (!str) return ''; return str.replace(/[&<>]/g, m => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' }[m])); }

        // Tab switching
        document.querySelectorAll('.tab-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active', 'bg-amber-500', 'text-black'));
                btn.classList.add('active', 'bg-amber-500', 'text-black');
                const tabId = btn.getAttribute('data-tab');
                document.querySelectorAll('.tab-content').forEach(c => c.classList.add('hidden'));
                document.getElementById(`tab-${tabId}`).classList.remove('hidden');
                if (tabId === 'users') {
                    if (!hasUserSearch) {
                        renderEmptyUserMessage();
                    } else {
                        applyUserFilterAndPaginate();
                    }
                }
                if (tabId === 'ticket-codes') loadTicketCodes();
                if (tabId === 'point-logs') loadPointRedeemsLog();
                if (tabId === 'leaderboard') loadLeaderboardData();
                if (tabId === 'rewards') loadRewardsForAdmin();
            });
        });

        document.getElementById('search-user-btn')?.addEventListener('click', async () => {
            const searchTerm = document.getElementById('search-user-input').value;
            currentUserFilter = searchTerm;
            currentUserPage = 1;
            hasUserSearch = true;
            await fetchAllUsers();
            applyUserFilterAndPaginate();
        });

        document.getElementById('reset-user-btn')?.addEventListener('click', () => {
            document.getElementById('search-user-input').value = '';
            currentUserFilter = '';
            currentUserPage = 1;
            hasUserSearch = false;
            renderEmptyUserMessage();
        });

        document.getElementById('force-snapshot-btn')?.addEventListener('click', forceLeaderboardSnapshot);
        document.getElementById('delete-snapshots-btn')?.addEventListener('click', deleteAllSnapshots);
        document.getElementById('refresh-rewards-btn')?.addEventListener('click', loadRewardsForAdmin);

        (async () => {
            await loadAdminData();
            await fetchAllUsers();  // memuat user dan menampilkan latest users
            renderEmptyUserMessage();
            await loadLeaderboardData();
        })();
    </script>
</body>

</html>