const API = {
  async req(method, url, body = null) {
    const opts = { method, headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin' };
    if (body) opts.body = JSON.stringify(body);
    const res = await fetch(url, opts);
    const data = await res.json();
    if (!res.ok) throw new Error(data.error || 'Request failed');
    return data;
  },
  get: (url) => API.req('GET', url),
  post: (url, body) => API.req('POST', url, body),
  put: (url, body) => API.req('PUT', url, body),
  del: (url) => API.req('DELETE', url)
};

const State = {
  user: null,
  currentPage: 'dashboard',
  usersOffset: 0,
  usersLimit: 30,
  usersFilter: '',
  usersStatus: '',
  trafficChart: null,
  inbounds: {}
};

function toast(msg, type = 'info', duration = 3000) {
  const c = document.getElementById('toast-container');
  const el = document.createElement('div');
  el.className = `toast ${type}`;
  const icons = { success: '✓', error: '✕', info: 'ℹ' };
  el.innerHTML = `<span>${icons[type] || ''}</span><span>${msg}</span>`;
  c.appendChild(el);
  setTimeout(() => { el.style.opacity = '0'; el.style.transition = 'opacity 0.3s'; setTimeout(() => el.remove(), 300); }, duration);
}

function openModal(title, html, onClose) {
  document.getElementById('modal-title').textContent = title;
  document.getElementById('modal-body').innerHTML = html;
  document.getElementById('modal-overlay').classList.remove('hidden');
  document._modalCloseCallback = onClose;
}

function closeModal() {
  document.getElementById('modal-overlay').classList.add('hidden');
  if (document._modalCloseCallback) { document._modalCloseCallback(); document._modalCloseCallback = null; }
}

document.getElementById('modal-close').addEventListener('click', closeModal);
document.getElementById('modal-overlay').addEventListener('click', (e) => {
  if (e.target === document.getElementById('modal-overlay')) closeModal();
});

function formatBytes(bytes) {
  if (!bytes || bytes === 0) return '0 B';
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(1024));
  return (bytes / Math.pow(1024, i)).toFixed(2) + ' ' + sizes[i];
}

function formatBytesSpeed(bps) { return formatBytes(bps) + '/s'; }
function statusLabel(s) { const map = { active: 'فعال', expired: 'منقضی', on_hold: 'معلق', disabled: 'غیرفعال', limited: 'محدود' }; return map[s] || s; }
function trafficPercent(used, total) { if (!total || total === 0) return 0; return Math.min(100, Math.floor((used / total) * 100)); }
function trafficClass(pct) { if (pct >= 90) return 'traffic-high'; if (pct >= 60) return 'traffic-mid'; return 'traffic-low'; }
function formatDate(ts) { if (!ts) return '---'; const d = new Date(ts * 1000); return d.toLocaleDateString('fa-IR'); }
function daysLeft(ts) { if (!ts) return null; const diff = ts * 1000 - Date.now(); if (diff <= 0) return 0; return Math.ceil(diff / 86400000); }

function navigate(page) {
  State.currentPage = page;
  document.querySelectorAll('.nav-item').forEach(n => n.classList.toggle('active', n.dataset.page === page));
  document.querySelectorAll('.content-page').forEach(p => p.classList.toggle('active', p.id === `content-${page}`));
  closeSidebar();
  const loaders = { dashboard: loadDashboard, users: loadUsers, resellers: loadResellers, faq: loadFaq, settings: loadSettings };
  if (loaders[page]) loaders[page]();
}

async function checkAuth() {
  try {
    const data = await API.get('/api/auth/status');
    if (!data.configured) showPage('setup');
    else if (!data.loggedIn) showPage('login');
    else { State.user = data.user; showDashboard(); }
  } catch { showPage('login'); }
}
function showPage(name) { document.querySelectorAll('.page').forEach(p => p.classList.add('hidden')); document.getElementById(`page-${name}`).classList.remove('hidden'); }
function showDashboard() {
  showPage('main');
  const u = State.user;
  document.getElementById('sidebar-username').textContent = u.username;
  document.getElementById('sidebar-role').textContent = u.role === 'superadmin' ? 'ادمین' : 'نماینده';
  document.getElementById('sidebar-avatar').textContent = u.username[0].toUpperCase();
  document.querySelectorAll('.admin-only').forEach(el => { el.style.display = u.role === 'superadmin' ? '' : 'none'; });
  navigate('dashboard');
}

document.getElementById('setup-form')?.addEventListener('submit', async (e) => {
  e.preventDefault();
  const btn = document.getElementById('setup-btn');
  const err = document.getElementById('setup-error');
  btn.disabled = true; btn.textContent = 'در حال راه‌اندازی...'; err.classList.add('hidden');
  try {
    await API.post('/api/auth/setup', {
      panel_url: document.getElementById('setup-panel-url').value.trim(),
      panel_username: document.getElementById('setup-panel-user').value.trim(),
      panel_password: document.getElementById('setup-panel-pass').value,
      local_username: document.getElementById('setup-local-user').value.trim(),
      local_password: document.getElementById('setup-local-pass').value
    });
    toast('پنل با موفقیت راه‌اندازی شد', 'success');
    await checkAuth();
  } catch (ex) { err.textContent = ex.message; err.classList.remove('hidden'); }
  finally { btn.disabled = false; btn.innerHTML = '<span>راه‌اندازی پنل</span>'; }
});

document.getElementById('login-form')?.addEventListener('submit', async (e) => {
  e.preventDefault();
  const btn = document.getElementById('login-btn');
  const err = document.getElementById('login-error');
  btn.disabled = true; btn.textContent = 'در حال ورود...'; err.classList.add('hidden');
  try {
    const data = await API.post('/api/auth/login', { username: document.getElementById('login-user').value.trim(), password: document.getElementById('login-pass').value });
    State.user = { username: data.username, role: data.role };
    toast('خوش آمدید!', 'success');
    showDashboard();
  } catch (ex) { err.textContent = ex.message; err.classList.remove('hidden'); }
  finally { btn.disabled = false; btn.innerHTML = '<span>ورود</span>'; }
});

async function doLogout() { await API.post('/api/auth/logout', {}); State.user = null; showPage('login'); toast('خروج موفق', 'info'); }
document.getElementById('logout-btn')?.addEventListener('click', doLogout);
document.getElementById('logout-btn-mobile')?.addEventListener('click', doLogout);
document.getElementById('menu-toggle')?.addEventListener('click', () => { document.getElementById('sidebar').classList.add('open'); document.getElementById('sidebar-overlay').classList.add('show'); });
document.getElementById('sidebar-overlay')?.addEventListener('click', closeSidebar);
function closeSidebar() { document.getElementById('sidebar')?.classList.remove('open'); document.getElementById('sidebar-overlay')?.classList.remove('show'); }
document.querySelectorAll('.nav-item').forEach(n => { n.addEventListener('click', (e) => { e.preventDefault(); navigate(n.dataset.page); }); });

async function loadDashboard() {
  try {
    const stats = await API.get('/api/dashboard/stats');
    document.getElementById('stat-active').textContent = stats.activeUsers ?? '-';
    document.getElementById('stat-expired').textContent = stats.expiredUsers ?? '-';
    document.getElementById('stat-onhold').textContent = stats.onHoldUsers ?? '-';
    document.getElementById('stat-total').textContent = stats.totalUsers ?? '-';
    const ramPct = stats.memTotal ? Math.floor((stats.memUsed / stats.memTotal) * 100) : 0;
    document.getElementById('ram-text').textContent = `${formatBytes(stats.memUsed)} / ${formatBytes(stats.memTotal)}`;
    document.getElementById('ram-bar').style.width = ramPct + '%';
    const cpuPct = Math.min(100, Math.floor(stats.cpuUsage * 100));
    document.getElementById('cpu-text').textContent = cpuPct + '%';
    document.getElementById('cpu-bar').style.width = cpuPct + '%';
    document.getElementById('upload-speed').textContent = formatBytesSpeed(stats.inboundUploadSpeed);
    document.getElementById('download-speed').textContent = formatBytesSpeed(stats.inboundDownloadSpeed);
    renderTrafficChart(stats.trafficByHour || []);
  } catch (err) { toast('خطا در بارگذاری داشبورد: ' + err.message, 'error'); }
}
function renderTrafficChart(hourlyData) {
  const ctx = document.getElementById('traffic-chart').getContext('2d');
  if (State.trafficChart) State.trafficChart.destroy();
  const labels = hourlyData.map(h => h.hour);
  const data = hourlyData.map(h => h.bytes / (1024 * 1024 * 1024));
  State.trafficChart = new Chart(ctx, {
    type: 'bar', data: { labels, datasets: [{ data, backgroundColor: 'rgba(124,106,247,0.5)', borderColor: 'rgba(124,106,247,0.8)', borderWidth: 1, borderRadius: 3 }] },
    options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { callbacks: { label: (ctx) => formatBytes(hourlyData[ctx.dataIndex]?.bytes || 0) } } }, scales: { x: { ticks: { color: '#555570', font: { size: 10 }, maxRotation: 0 }, grid: { color: 'rgba(42,42,56,0.8)' } }, y: { ticks: { color: '#555570', font: { size: 10 }, callback: v => v + ' GB' }, grid: { color: 'rgba(42,42,56,0.8)' } } } }
  });
}
document.getElementById('refresh-dashboard')?.addEventListener('click', loadDashboard);

async function loadUsers() {
  const grid = document.getElementById('users-grid');
  grid.innerHTML = '<div class="loading-spinner"><div class="spinner"></div>در حال بارگذاری...</div>';
  try {
    const params = new URLSearchParams({ limit: State.usersLimit, offset: State.usersOffset });
    if (State.usersFilter) params.set('search', State.usersFilter);
    if (State.usersStatus) params.set('status', State.usersStatus);
    const data = await API.get(`/api/users?${params}`);
    const users = data.users || [];
    if (users.length === 0) { grid.innerHTML = `<div class="empty-state"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/></svg><p>کاربری یافت نشد</p></div>`; return; }
    grid.innerHTML = users.map(u => renderUserCard(u)).join('');
    grid.querySelectorAll('.user-card').forEach(card => { card.addEventListener('click', (e) => { if (!e.target.closest('button')) openUserDetail(card.dataset.username); }); });
    grid.querySelectorAll('[data-action="delete-user"]').forEach(btn => { btn.addEventListener('click', (e) => { e.stopPropagation(); confirmDeleteUser(btn.dataset.username); }); });
    grid.querySelectorAll('[data-action="reset-traffic"]').forEach(btn => { btn.addEventListener('click', (e) => { e.stopPropagation(); doResetTraffic(btn.dataset.username); }); });
    renderPagination(data.total || users.length);
  } catch (err) { grid.innerHTML = `<div class="empty-state"><p>خطا: ${err.message}</p></div>`; }
}
function renderUserCard(u) {
  const pct = trafficPercent(u.used_traffic, u.data_limit);
  const tc = trafficClass(pct);
  const days = daysLeft(u.expire);
  return `<div class="user-card" data-username="${u.username}"><div class="user-card-header"><div class="user-card-name">${u.username}</div><span class="status-badge status-${u.status}">${statusLabel(u.status)}</span></div><div class="user-card-info"><span>${u.data_limit ? formatBytes(u.used_traffic) + ' / ' + formatBytes(u.data_limit) : formatBytes(u.used_traffic) + ' / ∞'}</span><span>${days !== null ? days + ' روز مانده' : 'بدون انقضا'}</span></div><div class="user-traffic-bar"><div class="user-traffic-fill ${tc}" style="width:${pct}%"></div></div><div class="traffic-display"><span>${pct}% مصرف شده</span></div><div class="user-card-actions"><button class="btn-icon" data-action="reset-traffic" data-username="${u.username}" title="ریست ترافیک"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 11-2.12-9.36L23 10"/></svg></button><button class="btn-icon" data-action="delete-user" data-username="${u.username}" title="حذف"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="color:var(--accent-2)"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a1 1 0 011-1h4a1 1 0 011 1v2"/></svg></button></div></div>`;
}
function renderPagination(total) {
  const pag = document.getElementById('users-pagination');
  const pages = Math.ceil(total / State.usersLimit);
  const cur = Math.floor(State.usersOffset / State.usersLimit);
  if (pages <= 1) { pag.innerHTML = ''; return; }
  let html = '';
  if (cur > 0) html += `<button class="page-btn" data-p="${cur - 1}">‹</button>`;
  for (let i = Math.max(0, cur - 2); i <= Math.min(pages - 1, cur + 2); i++) html += `<button class="page-btn ${i === cur ? 'active' : ''}" data-p="${i}">${i + 1}</button>`;
  if (cur < pages - 1) html += `<button class="page-btn" data-p="${cur + 1}">›</button>`;
  pag.innerHTML = html;
  pag.querySelectorAll('.page-btn').forEach(btn => { btn.addEventListener('click', () => { State.usersOffset = parseInt(btn.dataset.p) * State.usersLimit; loadUsers(); }); });
}
let searchTimeout; document.getElementById('user-search')?.addEventListener('input', (e) => { clearTimeout(searchTimeout); searchTimeout = setTimeout(() => { State.usersFilter = e.target.value.trim(); State.usersOffset = 0; loadUsers(); }, 400); });
document.querySelectorAll('.filter-tab').forEach(tab => { tab.addEventListener('click', () => { document.querySelectorAll('.filter-tab').forEach(t => t.classList.remove('active')); tab.classList.add('active'); State.usersStatus = tab.dataset.status; State.usersOffset = 0; loadUsers(); }); });
document.getElementById('create-user-btn')?.addEventListener('click', () => openCreateUserModal());
async function openCreateUserModal(prefill = {}) {
  let inboundHtml = '';
  try { const data = await API.get('/api/users/meta/inbounds'); State.inbounds = data; inboundHtml = Object.entries(data).map(([proto, inbs]) => `<span class="section-label">${proto}</span><div class="inbound-list">${inbs.map(i => `<span class="inbound-chip" data-tag="${proto}:${i.tag}">${i.tag}</span>`).join('')}</div>`).join(''); } catch { inboundHtml = '<p style="color:var(--text-muted);font-size:12px">اینباندی یافت نشد</p>'; }
  openModal('کاربر جدید', `<div class="modal-form"><div class="form-group"><label>نام کاربری *</label><input type="text" id="cu-username" placeholder="user1" value="${prefill.username || ''}" /></div><div class="form-row"><div class="form-group"><label>حجم داده (GB)</label><input type="number" id="cu-traffic" placeholder="بدون محدودیت = خالی" min="0" step="0.5" value="${prefill.data_limit ? prefill.data_limit / 1073741824 : ''}" /></div><div class="form-group"><label>روز انقضا</label><input type="number" id="cu-expire-days" placeholder="بدون انقضا = خالی" min="1" /></div></div><div class="form-group"><label>پروتکل‌ها و اینباندها</label>${inboundHtml}</div><div class="modal-footer"><button class="btn-secondary" onclick="closeModal()">انصراف</button><button class="btn-primary" id="cu-submit-btn">ساخت کاربر</button></div></div>`);
  document.querySelectorAll('.inbound-chip').forEach(chip => { chip.addEventListener('click', () => chip.classList.toggle('selected')); });
  document.getElementById('cu-submit-btn').addEventListener('click', async () => {
    const username = document.getElementById('cu-username').value.trim(); if (!username) { toast('نام کاربری الزامی است', 'error'); return; }
    const trafficGB = parseFloat(document.getElementById('cu-traffic').value); const expireDays = parseInt(document.getElementById('cu-expire-days').value);
    const proxies = {}; const inboundsSelected = {};
    document.querySelectorAll('.inbound-chip.selected').forEach(chip => { const [proto, tag] = chip.dataset.tag.split(':'); if (!proxies[proto]) proxies[proto] = {}; if (!inboundsSelected[proto]) inboundsSelected[proto] = []; inboundsSelected[proto].push(tag); });
    const userData = { username, proxies, inbounds: inboundsSelected, data_limit: trafficGB ? Math.floor(trafficGB * 1024 * 1024 * 1024) : 0, expire: expireDays ? Math.floor(Date.now() / 1000) + expireDays * 86400 : null, status: 'active' };
    const btn = document.getElementById('cu-submit-btn'); btn.disabled = true; btn.textContent = 'در حال ساخت...';
    try { await API.post('/api/users', userData); toast('کاربر با موفقیت ساخته شد', 'success'); closeModal(); loadUsers(); } catch (ex) { toast('خطا: ' + ex.message, 'error'); btn.disabled = false; btn.textContent = 'ساخت کاربر'; }
  });
}
async function openUserDetail(username) {
  try { const u = await API.get(`/api/users/${username}`); const pct = trafficPercent(u.used_traffic, u.data_limit); const days = daysLeft(u.expire); const subLinks = u.links || u.subscription_url ? `<div class="form-group"><label>لینک اشتراک</label><div class="sub-link-box"><input type="text" value="${u.subscription_url || ''}" readonly /><button onclick="copyText('${u.subscription_url || ''}')"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg></button></div></div>` : ''; openModal(`کاربر: ${u.username}`, `<div><div class="user-detail-grid"><div class="user-detail-item"><div class="user-detail-label">وضعیت</div><div class="user-detail-value"><span class="status-badge status-${u.status}">${statusLabel(u.status)}</span></div></div><div class="user-detail-item"><div class="user-detail-label">ترافیک مصرفی</div><div class="user-detail-value">${formatBytes(u.used_traffic)}</div></div><div class="user-detail-item"><div class="user-detail-label">حجم کل</div><div class="user-detail-value">${u.data_limit ? formatBytes(u.data_limit) : 'نامحدود'}</div></div><div class="user-detail-item"><div class="user-detail-label">انقضا</div><div class="user-detail-value">${u.expire ? formatDate(u.expire) + (days !== null ? ` (${days} روز)` : '') : 'ندارد'}</div></div></div><div class="user-traffic-bar" style="margin-bottom:4px"><div class="user-traffic-fill ${trafficClass(pct)}" style="width:${pct}%"></div></div><div class="traffic-display" style="margin-bottom:16px"><span>${pct}% مصرف شده</span></div>${subLinks}<div class="modal-footer"><button class="btn-danger" onclick="confirmDeleteUser('${u.username}')">حذف</button><button class="btn-secondary" onclick="doResetTraffic('${u.username}')">ریست ترافیک</button><button class="btn-primary" onclick="toggleUserStatus('${u.username}', '${u.status}')">${u.status === 'active' ? 'غیرفعال کردن' : 'فعال کردن'}</button></div></div>`); } catch (ex) { toast('خطا در بارگذاری کاربر', 'error'); }
}
async function toggleUserStatus(username, currentStatus) { const newStatus = currentStatus === 'active' ? 'disabled' : 'active'; try { await API.put(`/api/users/${username}`, { status: newStatus }); toast('وضعیت کاربر تغییر کرد', 'success'); closeModal(); loadUsers(); } catch (ex) { toast('خطا: ' + ex.message, 'error'); } }
function confirmDeleteUser(username) { openModal('تأیید حذف', `<div class="confirm-body"><div class="confirm-icon">🗑️</div><p>آیا از حذف کاربر <strong>${username}</strong> مطمئن هستید؟</p><p style="margin-top:8px;font-size:12px;color:var(--accent-2)">این عمل قابل بازگشت نیست.</p><div class="modal-footer" style="justify-content:center;margin-top:20px"><button class="btn-secondary" onclick="closeModal()">انصراف</button><button class="btn-danger" id="confirm-del-btn">بله، حذف کن</button></div></div>`); document.getElementById('confirm-del-btn').addEventListener('click', async () => { try { await API.del(`/api/users/${username}`); toast(`کاربر ${username} حذف شد`, 'success'); closeModal(); loadUsers(); } catch (ex) { toast('خطا در حذف: ' + ex.message, 'error'); } }); }
async function doResetTraffic(username) { try { await API.post(`/api/users/${username}/reset`, {}); toast(`ترافیک ${username} ریست شد`, 'success'); loadUsers(); } catch (ex) { toast('خطا: ' + ex.message, 'error'); } }
function copyText(text) { navigator.clipboard.writeText(text).then(() => toast('کپی شد', 'success')); }

async function loadResellers() {
  const grid = document.getElementById('resellers-grid');
  grid.innerHTML = '<div class="loading-spinner"><div class="spinner"></div>در حال بارگذاری...</div>';
  try { const resellers = await API.get('/api/resellers'); if (!resellers.length) { grid.innerHTML = '<div class="empty-state"><p>هیچ نماینده‌ای وجود ندارد</p></div>'; return; } grid.innerHTML = resellers.map(r => renderResellerCard(r)).join(''); grid.querySelectorAll('[data-action="edit-reseller"]').forEach(btn => { btn.addEventListener('click', () => openEditResellerModal(JSON.parse(btn.dataset.reseller))); }); grid.querySelectorAll('[data-action="delete-reseller"]').forEach(btn => { btn.addEventListener('click', () => confirmDeleteReseller(btn.dataset.id, btn.dataset.name)); }); } catch (ex) { grid.innerHTML = `<div class="empty-state"><p>خطا: ${ex.message}</p></div>`; }
}
function renderResellerCard(r) { const trafficLimitGB = r.traffic_limit ? (r.traffic_limit / 1073741824).toFixed(1) : null; const usedGB = r.used_traffic ? (r.used_traffic / 1073741824).toFixed(2) : '0'; const tPct = trafficLimitGB ? Math.min(100, Math.floor((r.used_traffic / r.traffic_limit) * 100)) : 0; const uPct = r.user_limit ? Math.min(100, Math.floor((r.user_count / r.user_limit) * 100)) : 0; return `<div class="reseller-card"><div class="reseller-card-header"><div><div class="reseller-name">${r.display_name || r.username}</div><div class="reseller-username">${r.username}</div></div><span class="status-badge ${r.is_active ? 'status-active' : 'status-disabled'}">${r.is_active ? 'فعال' : 'غیرفعال'}</span></div><div class="reseller-stats"><div class="reseller-stat"><div class="reseller-stat-val">${r.user_count}</div><div class="reseller-stat-label">${r.user_limit ? 'از ' + r.user_limit : 'کاربر'}</div></div><div class="reseller-stat"><div class="reseller-stat-val">${usedGB}</div><div class="reseller-stat-label">GB ${trafficLimitGB ? 'از ' + trafficLimitGB : 'مصرفی'}</div></div></div>${trafficLimitGB ? `<div class="limit-bar-wrap"><div class="limit-bar-label"><span>ترافیک</span><span>${tPct}%</span></div><div class="limit-bar"><div class="limit-bar-fill" style="width:${tPct}%"></div></div></div>` : ''}${r.user_limit ? `<div class="limit-bar-wrap" style="margin-top:6px"><div class="limit-bar-label"><span>کاربران</span><span>${uPct}%</span></div><div class="limit-bar"><div class="limit-bar-fill" style="width:${uPct}%;background:var(--blue)"></div></div></div>` : ''}<div class="reseller-card-footer"><button class="btn-icon" data-action="edit-reseller" data-reseller='${JSON.stringify({id:r.id,username:r.username,display_name:r.display_name,traffic_limit:r.traffic_limit,user_limit:r.user_limit,is_active:r.is_active,notes:r.notes})}'><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></button><button class="btn-icon" data-action="delete-reseller" data-id="${r.id}" data-name="${r.username}"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="color:var(--accent-2)"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a1 1 0 011-1h4a1 1 0 011 1v2"/></svg></button></div></div>`; }
document.getElementById('create-reseller-btn')?.addEventListener('click', () => openCreateResellerModal());
function openCreateResellerModal() { openModal('نماینده جدید', `<div class="modal-form"><div class="form-group"><label>نام کاربری *</label><input type="text" id="cr-username" placeholder="reseller1" /></div><div class="form-group"><label>رمز عبور *</label><input type="password" id="cr-password" placeholder="حداقل ۸ کاراکتر" /></div><div class="form-group"><label>نام نمایشی</label><input type="text" id="cr-display" placeholder="نماینده شیراز" /></div><div class="form-row"><div class="form-group"><label>محدودیت ترافیک (GB)</label><input type="number" id="cr-traffic" placeholder="خالی = نامحدود" min="0" step="1" /></div><div class="form-group"><label>محدودیت کاربر</label><input type="number" id="cr-users" placeholder="خالی = نامحدود" min="0" /></div></div><div class="form-group"><label>یادداشت</label><textarea id="cr-notes" placeholder="اطلاعات بیشتر..."></textarea></div><div class="modal-footer"><button class="btn-secondary" onclick="closeModal()">انصراف</button><button class="btn-primary" id="cr-submit-btn">ساخت نماینده</button></div></div>`); document.getElementById('cr-submit-btn').addEventListener('click', async () => { const username = document.getElementById('cr-username').value.trim(); const password = document.getElementById('cr-password').value; if (!username || !password) { toast('نام کاربری و رمز الزامی است', 'error'); return; } const btn = document.getElementById('cr-submit-btn'); btn.disabled = true; btn.textContent = 'در حال ساخت...'; try { await API.post('/api/resellers', { username, password, display_name: document.getElementById('cr-display').value.trim(), traffic_limit: document.getElementById('cr-traffic').value || null, user_limit: document.getElementById('cr-users').value || 0, notes: document.getElementById('cr-notes').value }); toast('نماینده با موفقیت ساخته شد', 'success'); closeModal(); loadResellers(); } catch (ex) { toast('خطا: ' + ex.message, 'error'); btn.disabled = false; btn.textContent = 'ساخت نماینده'; } }); }
function openEditResellerModal(r) { const trafficGB = r.traffic_limit ? (r.traffic_limit / 1073741824).toFixed(1) : ''; openModal('ویرایش نماینده', `<div class="modal-form"><div class="form-group"><label>نام کاربری</label><input type="text" value="${r.username}" disabled /></div><div class="form-group"><label>رمز عبور جدید (خالی = بدون تغییر)</label><input type="password" id="er-password" placeholder="••••••••" /></div><div class="form-group"><label>نام نمایشی</label><input type="text" id="er-display" value="${r.display_name || ''}" /></div><div class="form-row"><div class="form-group"><label>محدودیت ترافیک (GB)</label><input type="number" id="er-traffic" value="${trafficGB}" min="0" /></div><div class="form-group"><label>محدودیت کاربر</label><input type="number" id="er-users" value="${r.user_limit || 0}" min="0" /></div></div><div class="form-group"><label>وضعیت</label><div class="toggle-wrap" style="margin-top:4px"><div class="toggle ${r.is_active ? 'on' : ''}" id="er-active-toggle"></div><span class="toggle-label" id="er-active-label">${r.is_active ? 'فعال' : 'غیرفعال'}</span></div></div><div class="modal-footer"><button class="btn-secondary" onclick="closeModal()">انصراف</button><button class="btn-primary" id="er-submit-btn">ذخیره</button></div></div>`); let isActive = r.is_active; document.getElementById('er-active-toggle').addEventListener('click', () => { isActive = !isActive; const tog = document.getElementById('er-active-toggle'); tog.classList.toggle('on', isActive); document.getElementById('er-active-label').textContent = isActive ? 'فعال' : 'غیرفعال'; }); document.getElementById('er-submit-btn').addEventListener('click', async () => { const btn = document.getElementById('er-submit-btn'); btn.disabled = true; btn.textContent = 'در حال ذخیره...'; try { const payload = { display_name: document.getElementById('er-display').value.trim(), traffic_limit: document.getElementById('er-traffic').value || null, user_limit: document.getElementById('er-users').value || 0, is_active: isActive }; const pass = document.getElementById('er-password').value; if (pass) payload.password = pass; await API.put(`/api/resellers/${r.id}`, payload); toast('نماینده بروزرسانی شد', 'success'); closeModal(); loadResellers(); } catch (ex) { toast('خطا: ' + ex.message, 'error'); btn.disabled = false; btn.textContent = 'ذخیره'; } }); }
function confirmDeleteReseller(id, name) { openModal('تأیید حذف نماینده', `<div class="confirm-body"><div class="confirm-icon">⚠️</div><p>آیا از حذف نماینده <strong>${name}</strong> مطمئن هستید؟</p><div class="modal-footer" style="justify-content:center;margin-top:20px"><button class="btn-secondary" onclick="closeModal()">انصراف</button><button class="btn-danger" id="confirm-del-res-btn">حذف</button></div></div>`); document.getElementById('confirm-del-res-btn').addEventListener('click', async () => { try { await API.del(`/api/resellers/${id}`); toast('نماینده حذف شد', 'success'); closeModal(); loadResellers(); } catch (ex) { toast('خطا: ' + ex.message, 'error'); } }); }

async function loadFaq() {
  const list = document.getElementById('faq-list');
  list.innerHTML = '<div class="loading-spinner"><div class="spinner"></div>در حال بارگذاری...</div>';
  try { const items = await API.get('/api/faq'); if (!items.length) { list.innerHTML = '<div class="empty-state"><p>سوالی اضافه نشده</p></div>'; return; } list.innerHTML = items.map(f => `<div class="faq-item" data-id="${f.id}"><div class="faq-question"><div style="display:flex;align-items:center;gap:8px;flex:1">${State.user?.role === 'superadmin' ? `<div class="faq-actions"><button class="btn-icon faq-edit" data-id="${f.id}" data-q="${encodeURIComponent(f.question)}" data-a="${encodeURIComponent(f.answer)}"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></button><button class="btn-icon faq-delete" data-id="${f.id}"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="color:var(--accent-2)"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a1 1 0 011-1h4a1 1 0 011 1v2"/></svg></button></div>` : ''}<span>${f.question}</span></div><svg class="faq-toggle-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg></div><div class="faq-answer">${f.answer}</div></div>`).join(''); list.querySelectorAll('.faq-question').forEach(q => { q.addEventListener('click', (e) => { if (e.target.closest('button')) return; q.parentElement.classList.toggle('open'); }); }); list.querySelectorAll('.faq-edit').forEach(btn => { btn.addEventListener('click', () => openFaqModal(btn.dataset.id, decodeURIComponent(btn.dataset.q), decodeURIComponent(btn.dataset.a))); }); list.querySelectorAll('.faq-delete').forEach(btn => { btn.addEventListener('click', () => deleteFaq(btn.dataset.id)); }); } catch (ex) { list.innerHTML = `<div class="empty-state"><p>خطا: ${ex.message}</p></div>`; } }
document.getElementById('create-faq-btn')?.addEventListener('click', () => openFaqModal());
function openFaqModal(id = null, question = '', answer = '') { openModal(id ? 'ویرایش سوال' : 'سوال جدید', `<div class="modal-form"><div class="form-group"><label>سوال</label><input type="text" id="faq-q" value="${question}" placeholder="سوال را بنویسید..." /></div><div class="form-group"><label>پاسخ</label><textarea id="faq-a" rows="4" placeholder="پاسخ را بنویسید...">${answer}</textarea></div><div class="modal-footer"><button class="btn-secondary" onclick="closeModal()">انصراف</button><button class="btn-primary" id="faq-save-btn">${id ? 'ذخیره' : 'افزودن'}</button></div></div>`); document.getElementById('faq-save-btn').addEventListener('click', async () => { const q = document.getElementById('faq-q').value.trim(); const a = document.getElementById('faq-a').value.trim(); if (!q || !a) { toast('سوال و پاسخ الزامی است', 'error'); return; } try { if (id) await API.put(`/api/faq/${id}`, { question: q, answer: a }); else await API.post('/api/faq', { question: q, answer: a }); toast('ذخیره شد', 'success'); closeModal(); loadFaq(); } catch (ex) { toast('خطا: ' + ex.message, 'error'); } }); }
async function deleteFaq(id) { try { await API.del(`/api/faq/${id}`); toast('حذف شد', 'success'); loadFaq(); } catch (ex) { toast('خطا: ' + ex.message, 'error'); } }

async function loadSettings() { try { const s = await API.get('/api/settings'); document.getElementById('setting-title').value = s.site_title || ''; document.getElementById('setting-support').value = s.support_link || ''; document.getElementById('setting-panel-url').value = s.panel_url || ''; } catch { } }
document.getElementById('save-settings-btn')?.addEventListener('click', async () => { try { await API.put('/api/settings', { site_title: document.getElementById('setting-title').value, support_link: document.getElementById('setting-support').value }); toast('تنظیمات ذخیره شد', 'success'); } catch (ex) { toast('خطا: ' + ex.message, 'error'); } });

window.copyText = copyText; window.closeModal = closeModal; window.confirmDeleteUser = confirmDeleteUser; window.doResetTraffic = doResetTraffic; window.toggleUserStatus = toggleUserStatus;

checkAuth();
