<?php
// modules/inventory/widgets/stock_table.php
if (basename($_SERVER['PHP_SELF']) == 'stock_table.php') { die('Access Denied'); }

global $pdo;
$serversList = [];
try {
    if (isset($pdo)) {
        $serversList = $pdo->query("SELECT * FROM servers ORDER BY id ASC")->fetchAll(PDO::FETCH_ASSOC);
    }
} catch (Exception $e) {}
?>

<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>

<style>
    .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_info { display: none !important; }
    .dataTables_wrapper .dataTables_length { display: flex !important; align-items: center; margin-bottom: 15px; font-size: 12px; font-weight: bold; color: #64748b; }
    .dataTables_wrapper .dataTables_length select { border: 2px solid #e2e8f0; border-radius: 8px; padding: 4px 25px 4px 10px; margin: 0 8px; outline: none; background: #f8fafc; color: #334155; cursor: pointer;}
    html.dark .dataTables_wrapper .dataTables_length select { background-color: #1e293b; color: #f8fafc; border-color: #334155; }
    .dataTables_wrapper .dataTables_paginate { margin-top: 1.5rem !important; display: flex; justify-content: center; width: 100%; }
    .dataTables_wrapper .dataTables_paginate .paginate_button { border-radius: 6px !important; border: 1px solid #e2e8f0 !important; background: #fff !important; margin: 0 3px !important; padding: 4px 10px !important; font-weight: bold; font-size: 12px; cursor: pointer; color: #64748b !important; }
    html.dark .dataTables_wrapper .dataTables_paginate .paginate_button { background-color: #1e293b !important; color: #94a3b8 !important; border-color: #334155 !important; }
    .dataTables_wrapper .dataTables_paginate .paginate_button.current { background-color: #3b5998 !important; color: #fff !important; border-color: #3b5998 !important; }
    table.dataTable tbody tr { background-color: transparent !important; }
    table.dataTable.no-footer { border-bottom: none !important; }
    .tiny-scrollbar::-webkit-scrollbar { width: 4px; }
    .tiny-scrollbar::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
    html.dark .tiny-scrollbar::-webkit-scrollbar-thumb { background: #475569; }
</style>

<div class="bg-white dark:bg-slate-800 rounded-3xl shadow-sm border border-gray-200 dark:border-slate-700 overflow-visible mb-16">
    <div class="flex flex-col md:flex-row justify-between items-center gap-4 bg-gray-50 dark:bg-slate-700/50 p-6 border-b border-gray-200 dark:border-slate-700 rounded-t-3xl">
        <div class="flex flex-wrap items-center gap-3 w-full md:w-auto">
            <div class="relative w-full md:w-[200px]">
                <svg class="absolute left-3 top-2.5 w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
                <input type="text" id="customInvSearch" placeholder="جستجوی یوزرنیم..." class="w-full bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 text-gray-700 dark:text-gray-200 rounded-xl pl-9 pr-4 py-2 text-xs outline-none focus:ring-1 focus:ring-[#3b5998] transition shadow-sm">
            </div>
            
            <select id="filter_plan" class="border border-gray-200 dark:border-slate-600 rounded-xl px-4 py-2 text-xs font-bold text-gray-700 dark:text-white focus:ring-1 focus:ring-[#3b5998] outline-none bg-white dark:bg-slate-800 shadow-sm">
                <option value="">همه طرح‌ها</option>
                <?php foreach($plansList as $p): ?>
                    <option value="<?php echo htmlspecialchars($p['plan_name']); ?>"><?php echo htmlspecialchars($p['plan_name']); ?></option>
                <?php endforeach; ?>
            </select>
            
            <select id="target_server_id" onchange="loadInventoryLive()" class="border-2 border-[#3b5998] rounded-xl px-4 py-2 text-xs font-bold text-[#3b5998] focus:ring-1 focus:ring-[#3b5998] outline-none bg-blue-50 dark:bg-[#3b5998]/20 dark:text-blue-300 shadow-sm cursor-pointer">
                <?php if(empty($serversList)): ?>
                    <option value="" disabled selected>سروری یافت نشد!</option>
                <?php else: ?>
                    <?php foreach($serversList as $index => $srv): ?>
                        <option value="<?php echo $srv['id']; ?>" <?php echo $index === 0 ? 'selected' : ''; ?>>
                            <?php echo htmlspecialchars($srv['name']); ?>
                        </option>
                    <?php endforeach; ?>
                <?php endif; ?>
            </select>
        </div>
        
        <div class="flex gap-2 w-full md:w-auto">
            <button onclick="loadInventoryLive()" class="p-2 text-gray-500 hover:bg-gray-200 dark:hover:bg-slate-600 bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-600 rounded-xl transition shadow-sm" title="دریافت مجدد دیتا">
                <svg id="refresh_inv_icon" 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"></path></svg>
            </button>
            <div class="flex bg-gray-200 dark:bg-slate-700 p-1 rounded-xl w-full md:w-auto shadow-sm">
                <button onclick="filterStatus('', this)" class="stat-btn flex-1 md:flex-none px-4 py-1.5 rounded-lg text-[11px] font-bold bg-white dark:bg-slate-600 text-gray-800 dark:text-white shadow-sm transition border border-gray-200 dark:border-slate-500">همه</button>
                <button onclick="filterStatus('available', this)" class="stat-btn flex-1 md:flex-none px-4 py-1.5 rounded-lg text-[11px] font-bold text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-white transition">موجود</button>
                <button onclick="filterStatus('sold', this)" class="stat-btn flex-1 md:flex-none px-4 py-1.5 rounded-lg text-[11px] font-bold text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-white transition">فروخته شده</button>
            </div>
        </div>
    </div>

    <div id="inv_error_box" class="hidden py-8 text-center text-rose-500 font-bold text-sm bg-rose-50 dark:bg-rose-900/20 m-4 rounded-xl border border-rose-200 dark:border-rose-800/50"></div>

    <div id="inv_loading_overlay" class="py-16 text-center block">
        <div class="inline-block animate-spin w-6 h-6 border-2 border-[#3b5998] border-t-transparent rounded-full mb-3"></div>
        <p class="text-xs font-bold text-gray-500">در حال دریافت و تطبیق اطلاعات سرور...</p>
    </div>

    <div id="inv_table_container" class="hidden w-full p-6">
        <div id="inventory_summary_cards" class="mb-6"></div>

        <div class="overflow-x-auto custom-scrollbar">
            <table id="inventoryTable" class="w-full text-left" dir="ltr">
                <thead class="bg-gray-100 dark:bg-slate-700 text-gray-700 dark:text-gray-300 text-[11px]">
                    <tr>
                        <th class="px-4 py-3 rounded-tl-xl"><div class="flex items-center gap-2"><input type="checkbox" id="selectAllCheckbox" onclick="toggleSelectAll()" class="rounded border-gray-300 mr-2 text-[#3b5998] focus:ring-[#3b5998] cursor-pointer"> Username</div></th>
                        <th class="px-4 py-3 font-normal min-w-[120px]">Status / Expire</th>
                        <th class="px-4 py-3 font-normal min-w-[250px]">Data Usage</th>
                        <th class="px-4 py-3 font-normal text-right min-w-[150px]" dir="rtl">وضعیت و مشخصات فروش</th>
                        <th class="px-2 py-3 font-normal text-right min-w-[170px] rounded-tr-xl">Actions</th>
                    </tr>
                </thead>
                <tbody id="inventory_table_body" class="divide-y divide-gray-100 dark:divide-slate-700/50 text-sm">
                    </tbody>
            </table>
        </div>
    </div>
</div>

<div id="bulk_action_bar" class="fixed bottom-6 left-1/2 transform -translate-x-1/2 bg-gray-900 dark:bg-slate-800 text-white px-5 py-3 rounded-2xl shadow-[0_10px_40px_rgba(0,0,0,0.3)] flex items-center gap-4 transition-all duration-300 translate-y-24 opacity-0 z-50 border border-gray-700 dark:border-slate-600">
    <span class="text-xs font-bold bg-gray-800 dark:bg-slate-700 px-3 py-1.5 rounded-lg flex items-center gap-2">
        <span id="bulk_count" class="bg-[#3b5998] px-1.5 rounded text-white">0</span> انتخاب شده
    </span>
    <div class="h-6 w-px bg-gray-700 dark:bg-slate-600"></div>
    <button onclick="executeBulk('active')" class="text-xs font-bold text-gray-300 hover:text-emerald-400 transition">فعال‌سازی</button>
    <button onclick="executeBulk('disabled')" class="text-xs font-bold text-gray-300 hover:text-rose-400 transition">مسدود</button>
    <button onclick="executeBulk('reset')" class="text-xs font-bold text-gray-300 hover:text-amber-400 transition">ریست حجم</button>
    <div class="h-6 w-px bg-gray-700 dark:bg-slate-600"></div>
    <button onclick="executeBulk('delete')" class="text-xs font-bold text-rose-500 hover:text-rose-400 transition">حذف کامل</button>
</div>

<div id="editDbItemModal" class="fixed inset-0 bg-black/50 hidden items-center justify-center z-[110] p-4 backdrop-blur-sm">
    <div class="bg-white dark:bg-slate-800 rounded-2xl p-6 max-w-4xl w-full shadow-2xl flex flex-col md:flex-row gap-6 max-h-[90vh]">
        <div class="w-full md:w-1/2 overflow-y-auto">
            <h2 class="text-xl font-bold mb-6 dark:text-white flex items-center gap-2">📝 ویرایش محصول در دیتابیس</h2>
            <form method="POST" action="inventory.php" class="space-y-4">
                <input type="hidden" name="action" value="edit_item"><input type="hidden" name="item_id" id="edit_db_item_id">
                <div><label class="block text-xs font-bold text-gray-500 mb-2">Username</label><input type="text" name="account_username" id="edit_db_username" required class="w-full border border-gray-200 dark:border-slate-600 p-3 rounded-xl bg-gray-50 dark:bg-slate-700 dark:text-white font-mono text-sm" dir="ltr"></div>
                <div><label class="block text-xs font-bold text-gray-500 mb-2">Sub Link</label><textarea name="config_link" id="edit_db_link" rows="4" required class="w-full border border-gray-200 dark:border-slate-600 p-3 rounded-xl bg-gray-50 dark:bg-slate-700 dark:text-white font-mono text-xs" dir="ltr" oninput="updateIframePreview(this.value)"></textarea></div>
                <div class="flex gap-2 mt-4"><button type="submit" class="flex-1 bg-[#3b5998] text-white py-3 rounded-xl font-bold shadow-sm hover:bg-blue-800 transition">ذخیره</button><button type="button" onclick="$('#editDbItemModal').addClass('hidden').removeClass('flex')" class="flex-1 bg-gray-100 dark:bg-slate-700 text-gray-600 dark:text-white py-3 rounded-xl font-bold transition">لغو</button></div>
            </form>
        </div>
        <div class="w-full md:w-1/2 flex flex-col"><h3 class="text-sm font-bold text-[#3b5998] mb-4">🔍 پیش‌نمایش لینک</h3><div class="bg-gray-100 dark:bg-slate-900 rounded-2xl flex-1 border border-gray-200 dark:border-slate-700"><iframe id="sub_link_preview" class="w-full h-full min-h-[300px] rounded-2xl"></iframe></div></div>
    </div>
</div>

<div id="qrModal" class="fixed inset-0 bg-black/60 hidden items-center justify-center z-[110] p-4 backdrop-blur-sm">
    <div class="bg-[#f8f9fa] dark:bg-slate-800 rounded-2xl max-w-4xl w-full shadow-2xl relative flex flex-col md:flex-row min-h-[400px] overflow-hidden">
        <button onclick="$('#qrModal').removeClass('flex').addClass('hidden');" class="absolute top-4 right-4 text-gray-400 hover:text-gray-700 dark:hover:text-white z-20">
            <svg class="w-5 h-5" 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"></path></svg>
        </button>
        <div class="w-full md:w-5/12 bg-[#f8f9fa] dark:bg-slate-800 p-8 flex flex-col items-center justify-center border-b md:border-b-0 md:border-r border-gray-200 dark:border-slate-700 relative">
            <h3 class="absolute top-6 left-6 text-sm font-bold text-gray-800 dark:text-gray-200 flex items-center gap-2" dir="ltr">
                <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="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm14 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1z"></path></svg>
                <span id="qr_modal_title" class="truncate max-w-[200px]"></span>
            </h3>
            <div id="qrcode_wrapper" class="bg-white p-3 rounded-xl shadow-sm mt-8 flex items-center justify-center min-w-[180px] min-h-[180px]"></div>
        </div>
        <div class="w-full md:w-7/12 bg-[#f4f5f7] dark:bg-slate-900/50 p-6 flex flex-col">
            <div class="flex justify-between items-center mb-4 mt-2">
                <h4 class="text-sm font-bold text-gray-700 dark:text-gray-300" dir="ltr">Configurations</h4>
                <button onclick="copyAllConfigsModal()" class="text-xs font-bold text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white transition flex items-center gap-1" dir="ltr">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"></path></svg> Copy All
                </button>
            </div>
            <div id="qr_configs_list" class="flex-1 overflow-y-auto tiny-scrollbar space-y-2 pr-2" dir="ltr"></div>
            <div id="qr_pagination" class="hidden mt-4 pt-4 border-t border-gray-200 dark:border-slate-700 items-center justify-center gap-3">
                <button onclick="qrPrevPage()" id="qr_btn_prev" class="p-1.5 bg-white dark:bg-slate-700 border border-gray-200 dark:border-slate-600 rounded disabled:opacity-50 transition hover:bg-gray-50"><svg class="w-4 h-4 text-gray-600 dark:text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg></button>
                <span id="qr_page_info" class="text-xs font-bold text-gray-600 dark:text-gray-400 font-mono">1 / 1</span>
                <button onclick="qrNextPage()" id="qr_btn_next" class="p-1.5 bg-white dark:bg-slate-700 border border-gray-200 dark:border-slate-600 rounded disabled:opacity-50 transition hover:bg-gray-50"><svg class="w-4 h-4 text-gray-600 dark:text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg></button>
            </div>
        </div>
    </div>
</div>

<div id="vpnUserModal" class="fixed inset-0 bg-black/50 hidden items-center justify-center z-[100] p-4 backdrop-blur-sm">
    <div class="bg-white dark:bg-slate-800 rounded-2xl max-w-4xl w-full shadow-2xl relative flex flex-col max-h-[90vh]">
        <div class="p-5 border-b border-gray-100 dark:border-slate-700 flex justify-between items-center">
            <h2 class="text-base font-black text-gray-800 dark:text-slate-100 flex items-center gap-2">
                <svg class="w-4 h-4 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"></path></svg>
                <span id="vpn_modal_title">ویرایش کاربر VPN</span>
            </h2>
            <button onclick="closeVpnUserModal()" class="text-gray-400 hover:text-gray-700 dark:hover:text-white">
                <svg class="w-5 h-5" 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"></path></svg>
            </button>
        </div>
        <div id="vpn_modal_loading" class="absolute inset-0 bg-white/80 dark:bg-slate-800/80 z-10 flex items-center justify-center hidden">
            <div class="animate-spin w-8 h-8 border-4 border-[#3b5998] border-t-transparent rounded-full"></div>
        </div>
        <div class="flex-1 overflow-y-auto p-5 grid grid-cols-1 md:grid-cols-3 gap-6" dir="rtl">
            <div class="md:col-span-2 space-y-5">
                <div class="grid grid-cols-2 gap-4">
                    <div><label class="block text-[11px] font-bold text-gray-500 dark:text-gray-400 mb-1.5">نام کاربری</label><input type="text" id="vpn_modal_username" dir="ltr" readonly class="w-full bg-gray-100 dark:bg-slate-900 border border-gray-200 dark:border-slate-600 p-2.5 rounded-lg text-sm text-gray-500 cursor-not-allowed font-mono"></div>
                    <div><label class="block text-[11px] font-bold text-gray-500 dark:text-gray-400 mb-1.5">وضعیت اکانت</label><select id="vpn_modal_status" class="w-full border border-gray-200 dark:border-slate-600 p-2.5 rounded-lg bg-white dark:bg-slate-700 dark:text-white text-sm"><option value="active">فعال</option><option value="disabled">مسدود</option><option value="on_hold">در انتظار</option></select></div>
                </div>
                <div class="grid grid-cols-3 gap-4">
                    <div><label class="block text-[11px] font-bold text-gray-500 dark:text-gray-400 mb-1.5">سقف حجم (GB)</label><input type="number" id="vpn_modal_limit" step="0.01" min="0" dir="ltr" class="w-full border border-gray-200 dark:border-slate-600 p-2.5 rounded-lg bg-gray-50 dark:bg-slate-700 dark:text-white text-sm"></div>
                    <div><label class="block text-[11px] font-bold text-gray-500 dark:text-gray-400 mb-1.5">ریست دوره‌ای</label><select id="vpn_modal_reset" class="w-full border border-gray-200 dark:border-slate-600 p-2.5 rounded-lg bg-white dark:bg-slate-700 dark:text-white text-sm"><option value="no_reset">بدون ریست</option><option value="day">روزانه</option><option value="week">هفتگی</option><option value="month">ماهانه</option></select></div>
                    <div><label class="block text-[11px] font-bold text-gray-500 dark:text-gray-400 mb-1.5">تاریخ انقضا</label><input type="datetime-local" id="vpn_modal_expire" dir="ltr" class="w-full border border-gray-200 dark:border-slate-600 p-2.5 rounded-lg bg-gray-50 dark:bg-slate-700 dark:text-white text-[11px]"></div>
                </div>
                <div><label class="block text-[11px] font-bold text-gray-500 dark:text-gray-400 mb-1.5">یادداشت سرور</label><textarea id="vpn_modal_note" rows="2" class="w-full border border-gray-200 dark:border-slate-600 p-2.5 rounded-lg bg-gray-50 dark:bg-slate-700 dark:text-white text-sm"></textarea></div>
                <div class="border border-gray-200 dark:border-slate-600 rounded-lg overflow-hidden">
                    <div class="px-4 py-3 bg-gray-50 dark:bg-slate-700/50 rounded-t-lg"><span class="text-xs font-bold text-gray-700 dark:text-gray-200">🔒 پروتکل‌ها</span></div>
                    <div class="p-4 flex flex-wrap gap-4 bg-white dark:bg-slate-800" dir="ltr">
                        <label class="flex items-center gap-1.5"><input type="checkbox" name="vpn_modal_proxies[]" value="vless" class="text-blue-600 rounded border-gray-300"> <span class="text-xs font-mono text-gray-600 dark:text-gray-300">VLESS</span></label>
                        <label class="flex items-center gap-1.5"><input type="checkbox" name="vpn_modal_proxies[]" value="vmess" class="text-blue-600 rounded border-gray-300"> <span class="text-xs font-mono text-gray-600 dark:text-gray-300">VMESS</span></label>
                        <label class="flex items-center gap-1.5"><input type="checkbox" name="vpn_modal_proxies[]" value="trojan" class="text-blue-600 rounded border-gray-300"> <span class="text-xs font-mono text-gray-600 dark:text-gray-300">TROJAN</span></label>
                        <label class="flex items-center gap-1.5"><input type="checkbox" name="vpn_modal_proxies[]" value="shadowsocks" class="text-blue-600 rounded border-gray-300"> <span class="text-xs font-mono text-gray-600 dark:text-gray-300">SHADOWSOCKS</span></label>
                    </div>
                </div>
            </div>
            <div class="md:col-span-1 border-r md:border-r-0 md:border-l border-gray-100 dark:border-slate-700 md:pr-6 pr-0 h-full flex flex-col">
                <div class="flex border-b border-gray-200 dark:border-slate-700 mb-3" dir="ltr"><button class="flex-1 pb-2 text-xs font-bold text-[#3b5998] border-b-2 border-[#3b5998]">Groups</button></div>
                <div class="flex-1 overflow-y-auto tiny-scrollbar pl-1" id="vpn_modal_groups_list" dir="ltr"></div>
            </div>
        </div>
        <div class="p-4 border-t border-gray-100 dark:border-slate-700 flex justify-end gap-2 bg-gray-50 dark:bg-slate-800/80 rounded-b-2xl">
            <button onclick="closeVpnUserModal()" class="px-5 py-2 text-xs font-bold text-gray-600 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition">انصراف</button>
            <button onclick="submitVpnUserModal()" id="btn_save_vpn_modal" class="px-6 py-2 text-xs font-bold text-white bg-[#3b5998] hover:bg-blue-800 rounded-lg transition shadow-sm">ذخیره اطلاعات</button>
        </div>
    </div>
</div>

<script id="inventory_db_data" type="application/json">
    <?php echo json_encode($inventoryList ?? [], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP) ?: '[]'; ?>
</script>

<script>
    window.addEventListener('DOMContentLoaded', function() {
        
        if (typeof jQuery === 'undefined' || typeof $ === 'undefined') {
            document.getElementById('inv_loading_overlay').classList.add('hidden');
            let errBox = document.getElementById('inv_error_box');
            errBox.innerHTML = '❌ کتابخانه jQuery لود نشده است. لطفاً مطمئن شوید فایل inventory.php به درستی jQuery را فراخوانی می‌کند.';
            errBox.classList.remove('hidden');
            return;
        }

        window.inventoryDbList = [];
        try {
            let dbData = document.getElementById('inventory_db_data').textContent;
            window.inventoryDbList = JSON.parse(dbData);
            if (!Array.isArray(window.inventoryDbList)) window.inventoryDbList = [];
        } catch(e) { window.inventoryDbList = []; }
        
        window.dtInventory = null;
        window.liveUsersDict = {};
        
        window.activeQrLinks = []; 
        window.currentQrPage = 1;
        window.QR_PER_PAGE = 5;

        if($('#target_server_id').length && $('#target_server_id').val() !== '') {
            loadInventoryLive();
        }

        $(document).on('click', function(e) { 
            let $target = $(e.target); 
            if (!$target.closest('.dropdown-menu').length && !$target.closest('button[onclick^="toggleMenu"]').length) { 
                $('.dropdown-menu').addClass('hidden'); 
            } 
        });
    }); 

    function getSelectedServerId() {
        return document.getElementById('target_server_id') ? document.getElementById('target_server_id').value : '';
    }

    function formatBytesToGB(bytes) { return bytes ? (bytes / (1024 * 1024 * 1024)).toFixed(2) : 0; }
    
    function formatBytesExact(bytes) {
        if (!+bytes || bytes <= 0) return '0 B';
        const k = 1024, dm = 2, sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
    }

    function getStatusBadge(status) {
        let icon = `<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.393c5.857-5.857 15.355-5.857 21.213 0"></path></svg>`;
        if (status === 'active') return `<span class="inline-flex items-center gap-1 bg-[#d1fae5] dark:bg-emerald-900/40 text-[#047857] dark:text-emerald-400 px-2 py-0.5 rounded-full text-[10px] font-bold border border-[#a7f3d0] dark:border-emerald-800">${icon} Active</span>`;
        if (status === 'disabled') return `<span class="inline-flex items-center gap-1 bg-gray-100 dark:bg-slate-700 text-gray-500 px-2 py-0.5 rounded-full text-[10px] font-bold border border-gray-200 dark:border-slate-600">Disabled</span>`;
        if (status === 'on_hold') return `<span class="inline-flex items-center gap-1 bg-[#e0e7ff] text-[#1d4ed8] px-2 py-0.5 rounded-full text-[10px] font-bold border border-[#bfdbfe]">On Hold</span>`;
        if (status === 'expired' || status === 'limited') return `<span class="inline-flex items-center gap-1 bg-[#fee2e2] text-[#be123c] px-2 py-0.5 rounded-full text-[10px] font-bold border border-[#fecaca]">${status === 'expired' ? 'Expired' : 'Limited'}</span>`;
        return `<span class="inline-flex items-center gap-1 bg-gray-50 text-gray-600 px-2 py-0.5 rounded-full text-[10px] font-bold border border-gray-200">${status}</span>`;
    }

    function toggleMenu(id) { 
        $('.dropdown-menu').not('#' + id).addClass('hidden'); 
        $('#' + id).toggleClass('hidden'); 
    }

    // ==============================================
    // لود لایو اطلاعات، ساخت کارت‌های آمار و رندر جدول
    // ==============================================
    function loadInventoryLive() {
        try {
            let sId = getSelectedServerId();
            if(!sId) return;

            $('#refresh_inv_icon').addClass('animate-spin');
            
            if (!window.dtInventory) { 
                $('#inv_table_container').addClass('hidden'); 
                $('#inv_loading_overlay').removeClass('hidden'); 
            }
            $('#inv_error_box').addClass('hidden');

            $.ajax({ 
                url: '../pasarguard/pasarguard_api.php', 
                type: 'GET',
                data: { ajax_call: 'users_list', server_id: sId },
                dataType: 'json' 
            }).done(function(uData) {
                $('#refresh_inv_icon').removeClass('animate-spin');
                $('#inv_loading_overlay').addClass('hidden');

                if (uData && uData.error) { 
                    $('#inv_error_box').html('❌ خطا از سرور: ' + uData.error).removeClass('hidden'); 
                    return; 
                }

                let usersList = Array.isArray(uData) ? uData : (uData.users || uData.data || []);
                window.liveUsersDict = {};
                usersList.forEach(u => {
                    if(u && u.username) { window.liveUsersDict[u.username] = u; }
                });

                let filteredDbList = window.inventoryDbList.filter(item => (item.server_id == sId) || (!item.server_id && sId == 1));
                renderInventoryTable(filteredDbList);

            }).fail(function(xhr, status, error) {
                $('#refresh_inv_icon').removeClass('animate-spin');
                $('#inv_loading_overlay').addClass('hidden');
                $('#inv_error_box').html('❌ خطا در ارتباط با سرور VPN.').removeClass('hidden');
                
                let filteredDbList = window.inventoryDbList.filter(item => (item.server_id == sId) || (!item.server_id && sId == 1));
                renderInventoryTable(filteredDbList);
            });
        } catch (e) {
            $('#inv_loading_overlay').addClass('hidden');
            $('#inv_error_box').html('❌ خطای جاوااسکریپت: ' + e.message).removeClass('hidden');
        }
    }

    function renderInventoryTable(dbList) {
        if (window.dtInventory) { window.dtInventory.destroy(); }
        
        // 💡 1. محاسبه و ساخت کارت‌های آماری به تفکیک طرح (در بالای جدول)
        let summary = { available: { count: 0, vol: 0 }, sold: { count: 0, vol: 0 }, plans: {} };
        
        dbList.forEach(item => {
            let vol = parseFloat(item.volume) || 0;
            let plan = item.plan_name || 'سایر';
            if (!summary.plans[plan]) summary.plans[plan] = { available: { count: 0, vol: 0 }, sold: { count: 0, vol: 0 } };
            
            if (item.status === 'available') {
                summary.available.count++;
                summary.available.vol += vol;
                summary.plans[plan].available.count++;
                summary.plans[plan].available.vol += vol;
            } else {
                summary.sold.count++;
                summary.sold.vol += vol;
                summary.plans[plan].sold.count++;
                summary.plans[plan].sold.vol += vol;
            }
        });
        
        let sumHtml = `<div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3 mb-4">`;
        sumHtml += `<div class="bg-emerald-50 dark:bg-emerald-900/20 border border-emerald-100 dark:border-emerald-800 p-3 rounded-2xl flex flex-col items-center justify-center">
            <span class="text-[10px] font-bold text-emerald-600 dark:text-emerald-400 mb-1">کل موجودی انبار</span>
            <span class="text-lg font-black text-emerald-700 dark:text-emerald-300">${summary.available.count} <span class="text-[10px] font-normal">(${summary.available.vol}G)</span></span>
        </div>`;
        sumHtml += `<div class="bg-gray-50 dark:bg-slate-700/50 border border-gray-200 dark:border-slate-600 p-3 rounded-2xl flex flex-col items-center justify-center">
            <span class="text-[10px] font-bold text-gray-500 dark:text-gray-400 mb-1">کل محصولات فروخته شده</span>
            <span class="text-lg font-black text-gray-700 dark:text-gray-300">${summary.sold.count} <span class="text-[10px] font-normal">(${summary.sold.vol}G)</span></span>
        </div>`;
        
        Object.keys(summary.plans).forEach(p => {
            let pData = summary.plans[p];
            if(pData.available.count > 0 || pData.sold.count > 0) {
                sumHtml += `<div class="bg-blue-50/50 dark:bg-blue-900/10 border border-blue-100 dark:border-blue-800/50 p-2 rounded-2xl flex flex-col items-center justify-center relative overflow-hidden">
                    <span class="text-[11px] font-bold text-blue-800 dark:text-blue-300 mb-1.5">${p}</span>
                    <div class="flex gap-2 w-full justify-around px-1">
                        <div class="text-center"><div class="text-[9px] text-gray-400">موجود</div><div class="text-[10px] font-black text-emerald-600 dark:text-emerald-400">${pData.available.count}<span class="text-[8px] font-normal">(${pData.available.vol}G)</span></div></div>
                        <div class="w-px bg-blue-100 dark:bg-blue-800/50"></div>
                        <div class="text-center"><div class="text-[9px] text-gray-400">فروخته شده</div><div class="text-[10px] font-black text-gray-600 dark:text-gray-400">${pData.sold.count}<span class="text-[8px] font-normal">(${pData.sold.vol}G)</span></div></div>
                    </div>
                </div>`;
            }
        });
        sumHtml += `</div>`;
        $('#inventory_summary_cards').html(sumHtml);

        // 💡 2. ساخت ردیف‌های جدول و اطلاعات نماینده/تاریخ
        let html = '';
        
        dbList.forEach((item, idx) => {
            let uName = item.account_username || 'Unknown';
            let safeUName = String(uName).replace(/'/g, "\\'"); 
            let liveData = window.liveUsersDict[uName] || null;
            let safeItemLink = item.config_link ? String(item.config_link).replace(/'/g, "\\'") : '';
            
            let isOnline = false;
            let statusBadge = `<span class="inline-flex items-center gap-1 bg-rose-50 dark:bg-rose-900/30 text-rose-700 dark:text-rose-400 px-2 py-0.5 rounded-full text-[10px] font-bold border border-rose-200 dark:border-rose-800">در سرور یافت نشد</span>`;
            let expireText = '';
            let usageHtml = `<span class="text-[9px] text-rose-500 font-bold bg-rose-50 dark:bg-rose-900/30 px-2 py-1 rounded border border-rose-100 dark:border-rose-800">-</span>`;
            let dotColor = 'bg-transparent border border-gray-300 dark:border-slate-500';
            
            if (liveData) {
                isOnline = liveData.online === true || liveData.status === 'online' || liveData.status === 'active';
                dotColor = isOnline ? 'bg-emerald-500 shadow-[0_0_5px_rgba(16,185,129,0.5)]' : 'bg-transparent border border-gray-300';
                statusBadge = getStatusBadge(liveData.status);
                expireText = liveData.expire ? "⏳ " + new Date(liveData.expire).toLocaleDateString('fa-IR') : "⏳ نامحدود";
                
                let limitGB = formatBytesToGB(liveData.data_limit);
                let percent = (limitGB > 0) ? Math.min(100, Math.round((liveData.used_traffic / liveData.data_limit) * 100)) : 0;
                
                usageHtml = `
                <div class="flex flex-col gap-1 w-full max-w-[200px]">
                    <div class="w-full bg-[#e2e8f0] dark:bg-slate-700 rounded-full h-1 overflow-hidden mt-1">
                        <div class="bg-[#3b5998] h-1 rounded-full" style="width: ${percent}%"></div>
                    </div>
                    <div class="flex justify-between items-center text-[9px] font-bold text-gray-500 mt-1">
                        <span>0 B / ${limitGB > 0 ? limitGB + ' GB' : '∞'}</span>
                        <span class="text-gray-400">Total: ${formatBytesExact(liveData.used_traffic)}</span>
                    </div>
                </div>`;
            }

            // نمایش نام دقیق نماینده و تاریخ بر اساس دیتابیس
                    let dbStatusBadge = '';
                    if (item.status === 'available') {
                        dbStatusBadge = `<span class="bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400 px-3 py-1 rounded-lg text-[11px] font-bold inline-block border border-emerald-200 dark:border-emerald-800">موجود در انبار</span>`;
                    } else {
                        let seller = item.fullname || 'مدیریت';
                        let rawDate = item.sold_at || item.created_at;
                        let soldDateStr = rawDate ? new Date(rawDate).toLocaleDateString('fa-IR', {year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute:'2-digit'}) : '';
                        let dateHtml = soldDateStr ? `<span class="text-[9px] text-gray-400 font-mono bg-gray-50 dark:bg-slate-800/50 px-1.5 py-0.5 rounded" dir="ltr">${soldDateStr}</span>` : '';
                        
                        dbStatusBadge = `
                        <div class="flex flex-col items-end gap-1.5">
                            <span class="bg-gray-100 text-gray-500 dark:bg-slate-700 px-3 py-1 rounded-lg text-[10px] inline-block font-bold border border-gray-200 dark:border-slate-600 mb-1">فروخته شده</span>
                            <span class="text-[9px] text-gray-600 dark:text-gray-300 font-bold bg-white dark:bg-slate-800 px-2 py-0.5 rounded-md border border-gray-100 dark:border-slate-600 shadow-sm flex items-center gap-1">
                                <svg class="w-2.5 h-2.5 text-[#3b5998]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path></svg> 
                                ${seller}
                            </span>
                            ${dateHtml}
                        </div>`;
                    }
            
            let deleteAction = item.status === 'available' 
                ? `<form method="POST" action="inventory.php" onsubmit="return confirm('حذف این کالا از انبار؟ (اکانت از سرور پاک نمی‌شود)');" class="w-full"><input type="hidden" name="action" value="delete_item"><input type="hidden" name="item_id" value="${item.id}"><button type="submit" class="w-full text-right px-4 py-2 hover:bg-rose-50 dark:hover:bg-rose-900/20 text-rose-500 flex items-center gap-2" dir="rtl"><svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path 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"></path></svg> حذف از انبار</button></form>` 
                : '';

            let planNameHtml = item.plan_name ? `${item.plan_name} (${item.volume}G)` : 'بدون طرح';

            html += `
            <tr class="border-b border-gray-100 dark:border-slate-700/50 hover:bg-[#f8fafc] dark:hover:bg-slate-700/30 transition group inv-row">
                <td class="px-4 py-3 min-w-[200px] chk-col-td">
                    <div class="flex items-center gap-3">
                        <input type="checkbox" class="user-checkbox w-3.5 h-3.5 rounded border-gray-300 text-[#3b5998] focus:ring-[#3b5998] cursor-pointer" value="${safeUName}" onchange="updateBulkActionBar()">
                        <span class="w-2 h-2 rounded-full ${dotColor} shrink-0"></span>
                        <div class="flex flex-col">
                            <span class="font-bold text-gray-800 dark:text-slate-200 text-xs truncate" title="${uName}">${uName}</span>
                            <span class="text-[9px] text-gray-500 font-bold bg-gray-100 dark:bg-slate-700 px-1 rounded inline-block w-max mt-0.5">${planNameHtml}</span>
                        </div>
                    </div>
                </td>
                <td class="px-4 py-3 min-w-[120px]">
                    ${statusBadge}
                    <div class="text-[9px] text-gray-400 mt-1 font-mono tracking-tight">${expireText}</div>
                </td>
                <td class="px-4 py-3 min-w-[250px]">${usageHtml}</td>
                <td class="px-4 py-3 text-right" data-search="${item.status}">${dbStatusBadge}</td>
                <td class="px-2 py-3 text-right">
                    <div class="flex justify-end gap-1.5 text-gray-400 items-center">
                        
                        <div class="relative group dropdown-wrapper">
                            <button onclick="copySubLinkDirect('${safeItemLink}', this)" class="p-1 hover:text-gray-700 dark:hover:text-gray-200 transition bg-[#3b5998] hover:bg-blue-800 text-white rounded px-2 py-1 shadow-sm opacity-0 group-hover:opacity-100 absolute -top-8 right-0 whitespace-nowrap z-10 font-bold text-[10px]" id="tooltip_sub_${idx}">کپی ساب‌اسکریپشن</button>
                            <button onclick="copySubLinkDirect('${safeItemLink}', this)" class="p-1 hover:text-gray-700 dark:hover:text-gray-200 transition">
                                <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg>
                            </button>
                        </div>
                        
                        <div class="relative inline-block dropdown-wrapper">
                            <button onclick="toggleMenu('copy_configs_${idx}')" class="p-1 hover:text-gray-700 dark:hover:text-gray-200 transition">
                                <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"></path></svg>
                            </button>
                            <div id="copy_configs_${idx}" class="dropdown-menu hidden absolute right-0 top-6 w-32 bg-white dark:bg-slate-800 border border-gray-100 dark:border-slate-700 rounded-lg shadow-xl z-50 text-left text-[11px] font-bold py-1">
                                <button onclick="copyConfigsDirect('${safeItemLink}', 'links', this)" class="w-full text-left px-4 py-2 hover:bg-gray-50 dark:hover:bg-slate-700 text-gray-700 dark:text-gray-200 flex items-center gap-2"><svg class="w-3 h-3 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h16"></path></svg> links</button>
                                <button onclick="copyConfigsDirect('${safeItemLink}', 'base64', this)" class="w-full text-left px-4 py-2 hover:bg-gray-50 dark:hover:bg-slate-700 text-gray-700 dark:text-gray-200 flex items-center gap-2"><svg class="w-3 h-3 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"></path></svg> links (base64)</button>
                            </div>
                        </div>

                        <button onclick="openQrModalDirect('${safeUName}', '${safeItemLink}')" class="p-1 hover:text-gray-700 dark:hover:text-gray-200 transition">
                            <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm14 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z"></path></svg>
                        </button>
                        
                        <div class="relative inline-block ml-1 dropdown-wrapper">
                            <button onclick="toggleMenu('menu_${idx}')" class="hover:text-gray-700 dark:hover:text-gray-200 transition p-1">
                                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="12" cy="12" r="1.5" fill="currentColor"></circle><circle cx="12" cy="5" r="1.5" fill="currentColor"></circle><circle cx="12" cy="19" r="1.5" fill="currentColor"></circle></svg>
                            </button>
                            <div id="menu_${idx}" class="dropdown-menu hidden absolute right-0 top-6 w-40 bg-white dark:bg-slate-800 border border-gray-100 dark:border-slate-700 rounded-lg shadow-xl z-[60] text-left text-[11px] font-bold py-1">
                                <div class="px-3 py-1 text-[9px] text-gray-400 uppercase text-right" dir="rtl">دیتابیس انبار</div>
                                <button onclick="openEditDbItem('${item.id}', '${safeUName}', '${safeItemLink}')" class="w-full text-right px-4 py-2 hover:bg-amber-50 dark:hover:bg-slate-700 text-gray-700 dark:text-gray-200 flex items-center gap-2" dir="rtl">✏️ ویرایش یوزرنیم/لینک</button>
                                ${deleteAction}
                                <div class="border-t border-gray-100 dark:border-slate-700 my-1"></div>
                                <div class="px-3 py-1 text-[9px] text-gray-400 uppercase text-right" dir="rtl">سرور VPN</div>
                                <button onclick="openVpnUserModal('${safeUName}')" class="w-full text-left px-4 py-2 hover:bg-gray-50 dark:hover:bg-slate-700 text-gray-700 dark:text-gray-200 flex items-center gap-2"><svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"></path></svg> ویرایش کاربر</button>
                                <button onclick="actionUserSingle('active', '${safeUName}')" class="w-full text-left px-4 py-2 hover:bg-emerald-50 dark:hover:bg-emerald-900/20 text-emerald-600 flex items-center gap-2"><div class="w-2 h-2 rounded-full bg-emerald-500"></div> فعال کردن</button>
                                <button onclick="actionUserSingle('disabled', '${safeUName}')" class="w-full text-left px-4 py-2 hover:bg-orange-50 dark:hover:bg-orange-900/20 text-orange-600 flex items-center gap-2"><div class="w-2 h-2 rounded-full bg-orange-500"></div> مسدود کردن</button>
                                <button onclick="actionUserSingle('reset', '${safeUName}')" class="w-full text-left px-4 py-2 hover:bg-blue-50 dark:hover:bg-blue-900/20 text-blue-600 flex items-center gap-2">🔄 ریست حجم</button>
                                <button onclick="actionUserSingle('delete', '${safeUName}')" class="w-full text-left px-4 py-2 hover:bg-rose-50 dark:hover:bg-rose-900/20 text-rose-500 flex items-center gap-2">✖ حذف از سرور</button>
                            </div>
                        </div>
                    </div>
                </td>
            </tr>`;
        });

        $('#inventory_table_body').html(html);
        $('#inv_table_container').removeClass('hidden');

        window.dtInventory = $('#inventoryTable').DataTable({ 
            "ordering": false,
            "pageLength": 50,
            "language": { "emptyTable": "محصولی برای این سرور در انبار یافت نشد." }
        });

        $('#customInvSearch').off('keyup').on('keyup', function() { window.dtInventory.search(this.value).draw(); });
        $('#filter_plan').off('change').on('change', function() { window.dtInventory.column(0).search(this.value).draw(); });
        
        $('#selectAllCheckbox').prop('checked', false);
        updateBulkActionBar();
    }

    function filterStatus(status, btn) {
        if(!window.dtInventory) return;
        window.dtInventory.column(3).search(status ? '^' + status + '$' : '', true, false).draw();
        $('.stat-btn').removeClass('bg-white dark:bg-slate-600 text-gray-800 dark:text-white shadow-sm border border-gray-200 dark:border-slate-500').addClass('text-gray-500 dark:text-gray-400');
        $(btn).addClass('bg-white dark:bg-slate-600 text-gray-800 dark:text-white shadow-sm border border-gray-200 dark:border-slate-500').removeClass('text-gray-500 dark:text-gray-400');
    }

    // ==============================================
    // 💡 توابع هوشمند کپی و QR با خواندن لینک از دیتابیس (بدون نیاز به استعلام مجدد)
    // ==============================================
    function copySubLinkDirect(link, btn) {
        if (!link || link === 'null' || link === 'undefined' || link.trim() === '') { alert('لینک ساب در دیتابیس موجود نیست.'); return; }
        navigator.clipboard.writeText(link).then(() => { 
            let old = btn.innerHTML;
            btn.innerHTML = "<span class='text-emerald-500 font-bold text-[10px]'>کپی شد!</span>";
            setTimeout(() => { btn.innerHTML = old; }, 1500);
        });
    }

    function copyConfigsDirect(link, type, btnElement) {
        if (!link || link === 'null' || link === 'undefined' || link.trim() === '') { alert('لینک ساب در دیتابیس موجود نیست.'); return; }
        let oldText = btnElement.innerHTML;
        btnElement.innerHTML = `<span class="animate-pulse text-[10px]">استخراج...</span>`;
        let sId = getSelectedServerId() || 1;
        
        $.get('../pasarguard/pasarguard_api.php', {ajax_call: 'get_sub_links', sub_url: link, server_id: sId}, function(extractedLinks) {
            let linksArr = extractedLinks || [];
            if (!linksArr.length) { 
                alert('هیچ کانفیگی در این لینک یافت نشد.'); btnElement.innerHTML = oldText; return; 
            }
            let finalOutput = type === 'base64' ? btoa(unescape(encodeURIComponent(linksArr.join('\n')))) : linksArr.join('\n');
            navigator.clipboard.writeText(finalOutput).then(() => {
                btnElement.innerHTML = `<span class="text-emerald-500 text-[10px]">کپی شد!</span>`;
                setTimeout(() => { btnElement.innerHTML = oldText; $('.dropdown-menu').addClass('hidden'); }, 1500);
            });
        }, 'json').fail(function() { 
            alert('خطا در استخراج کانفیگ‌ها از لینک.'); 
            btnElement.innerHTML = oldText; 
        });
    }

    function openQrModalDirect(username, link) {
        $('.dropdown-menu').addClass('hidden');
        $('#qr_modal_title').text(username);
        $('#qr_configs_list').html('<div class="text-center text-gray-500 py-10 text-xs font-bold animate-pulse">در حال استخراج...</div>');
        $('#qrcode_wrapper').html('<div class="animate-spin w-8 h-8 border-4 border-[#3b5998] border-t-transparent rounded-full"></div>');
        $('#qr_pagination').addClass('hidden').removeClass('flex');
        $('#qrModal').removeClass('hidden').addClass('flex');

        if (!link || link === 'null' || link === 'undefined' || link.trim() === '') {
             $('#qrcode_wrapper').html('<div class="text-xs text-rose-500 font-bold text-center">لینک ساب<br>موجود نیست</div>');
             $('#qr_configs_list').html('<div class="text-center text-rose-500 py-10 text-xs font-bold">لینک ساب برای استخراج کانفیگ وجود ندارد.</div>');
             return;
        }

        let sId = getSelectedServerId() || 1;
        let qrContainer = document.getElementById("qrcode_wrapper");
        qrContainer.innerHTML = "";
        new QRCode(qrContainer, { text: link, width: 160, height: 160, colorDark : "#1e293b", colorLight : "#ffffff", correctLevel : QRCode.CorrectLevel.M });

        $.get('../pasarguard/pasarguard_api.php', {ajax_call: 'get_sub_links', sub_url: link, server_id: sId}, function(extractedLinks) {
            window.activeQrLinks = extractedLinks || []; 
            window.currentQrPage = 1;
            renderQrConfigsPage();
        }, 'json').fail(function() { 
            $('#qr_configs_list').html('<div class="text-center text-rose-500 py-10 text-xs font-bold">خطا در دریافت کانفیگ‌ها</div>');
        });
    }

    function renderQrConfigsPage() {
        let totalPages = Math.ceil(window.activeQrLinks.length / window.QR_PER_PAGE) || 1;
        if(window.currentQrPage > totalPages) window.currentQrPage = totalPages;
        if(window.currentQrPage < 1) window.currentQrPage = 1;

        let start = (window.currentQrPage - 1) * window.QR_PER_PAGE;
        let paginatedLinks = window.activeQrLinks.slice(start, start + window.QR_PER_PAGE);

        let listHtml = '';
        if(window.activeQrLinks.length === 0) {
            listHtml = '<div class="text-xs text-rose-500 py-6 text-center font-bold">هیچ کانفیگی یافت نشد.</div>';
            $('#qr_pagination').addClass('hidden').removeClass('flex');
        } else {
            paginatedLinks.forEach(cfg => {
                let name = 'Config', address = '-';
                try {
                    if(cfg.includes('#')) { name = decodeURIComponent(cfg.split('#')[1]); }
                    let match = cfg.match(/@([^:\/?]+)/);
                    if (match && match[1]) { address = match[1]; }
                } catch(e) {}
                let cfgB64 = btoa(unescape(encodeURIComponent(cfg)));
                listHtml += `
                <div class="bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-700 rounded-xl p-3 flex justify-between items-center shadow-sm">
                    <div class="overflow-hidden pr-2">
                        <h5 class="text-[11px] font-bold text-gray-800 dark:text-gray-200 truncate mb-1" title="${name}">${name}</h5>
                        <span class="bg-gray-100 dark:bg-slate-700 text-gray-500 dark:text-gray-400 px-2 py-0.5 rounded-full text-[9px]">${address}</span>
                    </div>
                    <button onclick="copySingleConfig('${cfgB64}', this)" class="shrink-0 p-1.5 text-gray-400 hover:text-[#3b5998] transition bg-gray-50 dark:bg-slate-700/50 rounded-lg">
                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"></path></svg>
                    </button>
                </div>`;
            });
            
            if (totalPages > 1) {
                $('#qr_pagination').removeClass('hidden').addClass('flex');
                $('#qr_page_info').text(`${window.currentQrPage} / ${totalPages}`);
                $('#qr_btn_prev').prop('disabled', window.currentQrPage === 1);
                $('#qr_btn_next').prop('disabled', window.currentQrPage === totalPages);
            } else {
                $('#qr_pagination').addClass('hidden').removeClass('flex');
            }
        }
        $('#qr_configs_list').html(listHtml);
    }

    function qrNextPage() { window.currentQrPage++; renderQrConfigsPage(); }
    function qrPrevPage() { window.currentQrPage--; renderQrConfigsPage(); }

    function copySingleConfig(b64Config, btnElement) {
        let configStr = decodeURIComponent(escape(atob(b64Config)));
        navigator.clipboard.writeText(configStr).then(() => {
            let original = btnElement.innerHTML;
            btnElement.innerHTML = `<span class="text-[10px] text-emerald-600 font-bold px-1">کپی شد</span>`;
            setTimeout(() => { btnElement.innerHTML = original; }, 1500);
        });
    }

    function copyAllConfigsModal() {
        if(window.activeQrLinks.length > 0) { navigator.clipboard.writeText(window.activeQrLinks.join('\n')).then(() => { alert('تمام کانفیگ‌ها کپی شدند.'); }); } 
        else { alert('هیچ کانفیگی وجود ندارد.'); }
    }

    function updateBulkActionBar() {
        let selected = $('.user-checkbox:checked').length;
        if (selected > 0) { $('#bulk_count').text(selected); $('#bulk_action_bar').removeClass('translate-y-24 opacity-0 pointer-events-none').addClass('translate-y-0 opacity-100'); } else { $('#bulk_action_bar').addClass('translate-y-24 opacity-0 pointer-events-none').removeClass('translate-y-0 opacity-100'); $('#selectAllCheckbox').prop('checked', false); }
    }
    
    function toggleSelectAll() { let isChecked = $('#selectAllCheckbox').prop('checked'); $('.user-checkbox').prop('checked', isChecked); updateBulkActionBar(); }

    function executeBulk(action) {
        let sId = getSelectedServerId();
        let checkboxes = $('.user-checkbox:checked');
        if (checkboxes.length === 0 || !confirm(`اجرای عملیات '${action}' روی ${checkboxes.length} کاربر در سرور VPN؟`)) return;
        $('#bulk_action_bar').addClass('opacity-50 pointer-events-none'); 
        let users = []; checkboxes.each(function() { users.push($(this).val()); });
        $.post('../pasarguard/pasarguard_api.php?ajax_call=bulk_action&server_id=' + sId, { bulk_type: action, usernames: users }, function(res) {
            $('#bulk_action_bar').removeClass('opacity-50 pointer-events-none'); 
            if (res && res.status === 'success') { loadInventoryLive(); } else alert('خطا.');
        }, 'json').fail(function() { alert('خطا در ارتباط با API'); $('#bulk_action_bar').removeClass('opacity-50 pointer-events-none'); });
    }
    
    function actionUserSingle(actionType, username) {
        $('.dropdown-menu').addClass('hidden');
        let sId = getSelectedServerId();
        if (!confirm(`اجرای عملیات روی سرور اصلی؟`)) return;
        $.post('../pasarguard/pasarguard_api.php?ajax_call=bulk_action&server_id=' + sId, { bulk_type: actionType, usernames: [username] }, function(res) {
            if (res && res.status === 'success') { loadInventoryLive(); } else alert('خطا.');
        }, 'json').fail(function() { alert('خطا در ارتباط با API'); });
    }

    function openEditDbItem(id, username, link) {
        $('.dropdown-menu').addClass('hidden'); $('#edit_db_item_id').val(id); $('#edit_db_username').val(username); $('#edit_db_link').val(link);
        updateIframePreview(link); $('#editDbItemModal').removeClass('hidden').addClass('flex');
    }
    function updateIframePreview(url) { document.getElementById('sub_link_preview').src = (url && (url.startsWith('http'))) ? url : 'about:blank'; }

    function openVpnUserModal(username) {
        $('.dropdown-menu').addClass('hidden'); 
        let sId = getSelectedServerId();
        $('#vpn_modal_username').val(username);
        $('#vpnUserModal').removeClass('hidden').addClass('flex'); 
        $('#vpn_modal_loading').removeClass('hidden');

        $.get('../pasarguard/pasarguard_api.php?ajax_call=groups&server_id=' + sId, function(res) {
            let groups = Array.isArray(res) ? res : (res.groups || res.data || []); let html = '';
            groups.forEach(g => { let gId = g.id !== undefined ? g.id : (g.value || ''); let gName = g.name || g.title || `Group ${gId}`; html += `<label class="flex items-center gap-2 p-2 hover:bg-gray-50 dark:hover:bg-slate-700/50 cursor-pointer rounded-lg"><input type="checkbox" name="vpn_modal_group_ids[]" value="${gId}" class="rounded border-gray-300 text-[#3b5998]"> <span class="text-xs text-gray-700 dark:text-gray-300">${gName}</span></label>`; });
            $('#vpn_modal_groups_list').html(html);
            
            // فراخوانی مستقیم و ایمن بجای fetchUserConfigs تو در تو
            $.get('../pasarguard/pasarguard_api.php', {ajax_call: 'get_user', username: username, server_id: sId}, function(userRes) {
                if(userRes && userRes.code === 200 && userRes.data) {
                    let u = userRes.data;
                    $('#vpn_modal_status').val(u.status || 'active'); 
                    $('#vpn_modal_limit').val(formatBytesToGB(u.data_limit));
                    $('#vpn_modal_note').val(u.note || ''); 
                    $('#vpn_modal_reset').val(u.data_limit_reset_strategy || 'no_reset');
                    if (u.expire) { let d = new Date(u.expire); d.setMinutes(d.getMinutes() - d.getTimezoneOffset()); $('#vpn_modal_expire').val(d.toISOString().slice(0,16)); } else { $('#vpn_modal_expire').val(''); }
                    $('input[name="vpn_modal_proxies[]"]').prop('checked', false);
                    if (u.proxies) { Object.keys(u.proxies).forEach(p => { $(`input[name="vpn_modal_proxies[]"][value="${p}"]`).prop('checked', true); }); }
                    $('input[name="vpn_modal_group_ids[]"]').prop('checked', false);
                    if (u.group_ids && Array.isArray(u.group_ids)) { u.group_ids.forEach(gId => { $(`input[name="vpn_modal_group_ids[]"][value="${gId}"]`).prop('checked', true); }); }
                    if (u.groups && Array.isArray(u.groups)) { u.groups.forEach(g => { $(`input[name="vpn_modal_group_ids[]"][value="${g.id || g.value}"]`).prop('checked', true); }); }
                }
                $('#vpn_modal_loading').addClass('hidden');
            }, 'json').fail(function() { alert('خطا در دریافت اطلاعات'); $('#vpnUserModal').addClass('hidden').removeClass('flex'); });
        }, 'json').fail(function() { alert('خطا در دریافت اطلاعات گروه‌ها'); $('#vpnUserModal').addClass('hidden').removeClass('flex'); });
    }

    function closeVpnUserModal() { $('#vpnUserModal').addClass('hidden').removeClass('flex'); }
    
    function submitVpnUserModal() {
        let username = $('#vpn_modal_username').val();
        let sId = getSelectedServerId();
        let data = { username: username, status: $('#vpn_modal_status').val(), data_limit_gb: $('#vpn_modal_limit').val() || 0, expire_date: $('#vpn_modal_expire').val() ? new Date($('#vpn_modal_expire').val()).toISOString() : '', note: $('#vpn_modal_note').val(), reset_strategy: $('#vpn_modal_reset').val(), proxies: [], group_ids: [] };
        $('input[name="vpn_modal_proxies[]"]:checked').each(function() { data.proxies.push($(this).val()); });
        $('input[name="vpn_modal_group_ids[]"]:checked').each(function() { data.group_ids.push(parseInt($(this).val())); });
        
        $('#btn_save_vpn_modal').attr('disabled', true).text('در حال ذخیره...');
        $.post('../pasarguard/pasarguard_api.php?ajax_call=edit_user&server_id=' + sId, data, function(res) {
            $('#btn_save_vpn_modal').attr('disabled', false).text('ذخیره تغییرات در سرور');
            if(res && (res.code === 200 || res.status === 'success')) { closeVpnUserModal(); loadInventoryLive(); } else { alert('خطا در ذخیره.'); }
        }, 'json').fail(function() { alert('خطا در ارتباط با API'); $('#btn_save_vpn_modal').attr('disabled', false).text('ذخیره تغییرات در سرور'); });
    }
</script>