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

<div id="debug_console" class="hidden my-4 bg-gray-900 border border-gray-700 rounded-2xl shadow-xl overflow-hidden relative">
    <div class="bg-gray-800 text-gray-300 px-4 py-3 border-b border-gray-700 flex justify-between items-center text-xs font-bold">
        <span class="flex items-center gap-2"><span>🛠</span> گزارش لحظه‌ای سیستم (Debugger)</span>
        <button onclick="$('#debug_console').addClass('hidden')" class="hover:text-white transition">بستن ✕</button>
    </div>
    <div id="debug_log_list" class="p-4 space-y-1.5 h-64 overflow-y-auto tiny-scrollbar" dir="ltr"></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>
    // سیستم دیباگر حرفه‌ای
    const SysDebug = {
        log: function(msg) { this.print(`[INFO] ${msg}`, 'text-blue-400'); },
        err: function(msg, raw = null) { 
            $('#debug_console').removeClass('hidden'); 
            this.print(`[ERROR] ${msg}`, 'text-rose-400 font-black'); 
            if(raw) this.print(`[RAW DETAIL] ${raw}`, 'text-rose-300 text-[10px] break-all');
        },
        success: function(msg) { this.print(`[SUCCESS] ${msg}`, 'text-emerald-400'); },
        print: function(text, classes) {
            let time = new Date().toLocaleTimeString('fa-IR');
            $('#debug_log_list').append(`<div class="text-[11px] font-mono mb-1 ${classes}"><span class="text-gray-500">[${time}]</span> ${text}</div>`);
            let consoleElem = document.getElementById('debug_log_list');
            if(consoleElem) consoleElem.scrollTop = consoleElem.scrollHeight;
        }
    };

    let inventoryDbList = [];
    let dtInventory = null;
    let liveUsersDict = {};
    
    // متغیرهای مودال QR 
    let activeQrLinks = []; 
    let currentQrPage = 1;
    const QR_PER_PAGE = 5;

    $(document).ready(function() {
        SysDebug.log("Initializing Inventory Module...");
        try {
            let dbData = document.getElementById('inventory_db_data').textContent;
            inventoryDbList = JSON.parse(dbData);
            if (!Array.isArray(inventoryDbList)) inventoryDbList = [];
            SysDebug.success(`Parsed local inventory DB. Items found: ${inventoryDbList.length}`);
        } catch(e) { 
            inventoryDbList = []; 
            SysDebug.err("Failed to parse inventory_db_data JSON", e.message);
        }

        if($('#target_server_id').length && $('#target_server_id').val() !== '') {
            loadInventoryLive();
        } else {
            SysDebug.err("Dropdown 'target_server_id' is missing or has no selected value.");
        }
    });

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

    // --- لود لایو ایمن شده و ضد کرش ---
    function loadInventoryLive() {
        try {
            let sId = getSelectedServerId();
            SysDebug.log(`loadInventoryLive triggered for Server ID: ${sId}`);

            if(!sId) {
                SysDebug.err("Server ID is null. Stopping execution.");
                $('#inv_loading_overlay').addClass('hidden');
                return;
            }

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

            // فیلتر کردن دیتابیس لوکال
            let filteredDbList = inventoryDbList.filter(item => (item.server_id == sId) || (!item.server_id && sId == 1));
            SysDebug.log(`Filtered local inventory items for this server: ${filteredDbList.length}`);

            SysDebug.log(`Sending AJAX to: pasarguard_api.php?ajax_call=users_list&server_id=${sId}`);
            
            $.ajax({ 
                url: '../pasarguard/pasarguard_api.php', 
                type: 'GET',
                data: { ajax_call: 'users_list', server_id: sId },
                dataType: 'json',
                timeout: 15000
            }).done(function(uData) {
                try {
                    SysDebug.success("AJAX Request Successful.");
                    $('#refresh_inv_icon').removeClass('animate-spin');
                    $('#inv_loading_overlay').addClass('hidden');

                    if (uData && uData.error) { 
                        SysDebug.err("API returned an explicit error:", uData.error);
                        $('#inv_error_box').html('❌ ' + uData.error).removeClass('hidden'); 
                        renderInventoryTable(filteredDbList);
                        return; 
                    }

                    let usersList = Array.isArray(uData) ? uData : (uData.users || uData.data || []);
                    SysDebug.log(`Server returned ${usersList.length} users.`);
                    
                    liveUsersDict = {};
                    usersList.forEach(u => {
                        if(u && u.username) { liveUsersDict[u.username] = u; }
                    });

                    renderInventoryTable(filteredDbList);
                } catch (e) {
                    SysDebug.err("JS Exception inside AJAX DONE block", e.message);
                    $('#refresh_inv_icon').removeClass('animate-spin');
                    $('#inv_loading_overlay').addClass('hidden');
                    $('#inv_error_box').html('❌ خطای داخلی جاوااسکریپت در نمایش جدول. دیباگر را ببینید.').removeClass('hidden');
                    renderInventoryTable(filteredDbList);
                }
            }).fail(function(xhr, status, error) {
                SysDebug.err(`AJAX FAILED! Status: ${status} | HTTP Error: ${error}`, xhr.responseText);
                $('#refresh_inv_icon').removeClass('animate-spin');
                $('#inv_loading_overlay').addClass('hidden');
                $('#inv_error_box').html('❌ خطا در ارتباط با سرور VPN. به لاگ دیباگر مراجعه کنید.').removeClass('hidden');
                renderInventoryTable(filteredDbList);
            });
        } catch (e) {
            $('#inv_loading_overlay').addClass('hidden');
            SysDebug.err("Fatal crash in loadInventoryLive", e.message);
        }
    }

    function renderInventoryTable(dbList) {
        try {
            SysDebug.log("Starting to render table...");
            if ($.fn.DataTable.isDataTable('#inventoryTable')) {
                $('#inventoryTable').DataTable().destroy();
            }
            
            let html = '';
            
            if (Array.isArray(dbList)) {
                dbList.forEach((item, idx) => {
                    let uName = item.account_username || 'Unknown';
                    let safeUName = String(uName).replace(/'/g, "\\'"); 
                    let liveData = liveUsersDict[uName] || null;
                    
                    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>${percent}% (${limitGB > 0 ? limitGB + 'GB' : '∞'})</span>
                                <span class="text-gray-400">Total: ${formatBytesExact(liveData.used_traffic)}</span>
                            </div>
                        </div>`;
                    }

                    let dbStatusBadge = item.status === 'available' 
                        ? `<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>` 
                        : `<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">فروخته شده</span>`;
                    
                    let safeItemId = item.id || 0;
                    let safeItemLink = item.config_link ? String(item.config_link).replace(/'/g, "\\'") : '';

                    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="${safeItemId}"><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="copySubLink('${safeUName}', 'sub_${idx}')" 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="copySubLink('${safeUName}', 'sub_${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"><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" title="Copy Configs">
                                        <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="copyConfigs('${safeUName}', '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="copyConfigs('${safeUName}', '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="openQrModal('${safeUName}')" class="p-1 hover:text-gray-700 dark:hover:text-gray-200 transition" title="Show QR Code">
                                    <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('${safeItemId}', '${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');

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

            $('#customInvSearch').off('keyup').on('keyup', function() { dtInventory.search(this.value).draw(); });
            $('#filter_plan').off('change').on('change', function() { dtInventory.column(0).search(this.value).draw(); });
            
            $('#selectAllCheckbox').prop('checked', false);
            updateBulkActionBar();
            SysDebug.success("Table rendered completely without errors.");
        } catch(e) {
            SysDebug.err("Fatal error during table render", e.message);
        }
    }

    // بقیه توابع (دقیقاً مشابه psg_users بدون هیچ تغییر)
    function filterStatus(status, btn) {
        if(!dtInventory) return;
        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');
    }

    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'); }
    $(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 fetchUserConfigs(username, callback) {
        try {
            let sId = getSelectedServerId();
            if(!sId) return;

            $.get('../pasarguard/pasarguard_api.php?ajax_call=get_user', {username: username, server_id: sId}, function(res) {
                if(res && res.code === 200 && res.data) {
                    let u = res.data;
                    let linksArr = u.links || u.configs || [];
                    let subUrl = u.subscription_url || u.sub_url || '';
                    
                    if (linksArr.length === 0 && subUrl) {
                        $.get('../pasarguard/pasarguard_api.php?ajax_call=get_sub_links', {sub_url: subUrl, server_id: sId}, function(extractedLinks) {
                            u.links = extractedLinks || [];
                            callback(u);
                        }, 'json').fail(function() { callback(u); });
                    } else { callback(u); }
                } else { alert('خطا در دریافت مستقیم اطلاعات کاربر از سرور.'); }
            }, 'json');
        } catch (err) { console.error(err); }
    }

    function copySubLink(username, btnIconId) {
        try {
            fetchUserConfigs(username, function(u) {
                let sub = u.subscription_url || u.sub_url;
                if (!sub) { alert('هیچ لینک سابی برای این کاربر وجود ندارد.'); return; }
                navigator.clipboard.writeText(sub).then(() => { 
                    let tooltip = document.getElementById('tooltip_' + btnIconId);
                    if(tooltip) tooltip.innerText = "کپی شد!";
                    setTimeout(() => { if(tooltip) tooltip.innerText = "کپی ساب‌اسکریپشن"; }, 1500);
                });
            });
        } catch(e) {}
    }

    function copyConfigs(username, type, btnElement) {
        try {
            let oldText = btnElement.innerHTML;
            btnElement.innerHTML = `<span class="animate-pulse">استخراج...</span>`;
            fetchUserConfigs(username, function(u) {
                let linksArr = u.links || [];
                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">کپی شد!</span>`;
                    setTimeout(() => { btnElement.innerHTML = oldText; $('.dropdown-menu').addClass('hidden'); }, 1500);
                });
            });
        } catch(e) {}
    }

    function openQrModal(username) {
        try {
            $('.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');

            fetchUserConfigs(username, function(u) {
                let sub = u.subscription_url || u.sub_url || '';
                activeQrLinks = u.links || []; 
                currentQrPage = 1;

                if (sub) {
                    let qrContainer = document.getElementById("qrcode_wrapper");
                    qrContainer.innerHTML = "";
                    new QRCode(qrContainer, { text: sub, width: 160, height: 160, colorDark : "#1e293b", colorLight : "#ffffff", correctLevel : QRCode.CorrectLevel.M });
                } else {
                    $('#qrcode_wrapper').html('<div class="text-xs text-rose-500 font-bold text-center">لینک ساب<br>موجود نیست</div>');
                }
                renderQrConfigsPage();
            });
        } catch (e) {}
    }

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

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

            let listHtml = '';
            if(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(`${currentQrPage} / ${totalPages}`);
                    $('#qr_btn_prev').prop('disabled', currentQrPage === 1);
                    $('#qr_btn_next').prop('disabled', currentQrPage === totalPages);
                } else {
                    $('#qr_pagination').addClass('hidden').removeClass('flex');
                }
            }
            $('#qr_configs_list').html(listHtml);
        } catch(e) {}
    }

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

    function copySingleConfig(b64Config, btnElement) {
        try {
            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);
            });
        } catch(e){}
    }

    function copyAllConfigsModal() {
        if(activeQrLinks.length > 0) { navigator.clipboard.writeText(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) {
        try {
            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');
        } catch(e){}
    }
    
    function actionUserSingle(actionType, username) {
        try {
            $('.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');
        } catch(e) {}
    }

    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) {
        try {
            $('.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(username, function(u) {
                    $('#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');
        } catch(e) {}
    }

    function closeVpnUserModal() { $('#vpnUserModal').addClass('hidden').removeClass('flex'); }
    
    function submitVpnUserModal() {
        try {
            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');
        } catch(e){}
    }
</script>