const API = '/api/product-desc';
let currentProducts = [];
let currentPage = 0;
let currentDetail = null;
let currentDetailCode = null;
const PAGE_SIZE = 30;

// ═══ Init ═══
window.addEventListener('DOMContentLoaded', () => {
  try {
    const parentParams = new URLSearchParams(window.parent.location.search);
    if (parentParams.has('p')) {
      currentPage = Math.max(0, parseInt(parentParams.get('p')) - 1) || 0;
    }
  } catch(e) {}
  
  loadOverview();
  loadFilters();
  loadProducts();
  // Enter to search
  document.getElementById('searchInput').addEventListener('keydown', e => {
    if (e.key === 'Enter') loadProducts();
  });
});

// ═══ Overview Stats ═══
async function loadOverview() {
  try {
    const res = await fetch(`${API}/overview`);
    const data = await res.json();
    if (data.status !== 'success') return;

    const totalSr  = data.total_sr  || 0;   // StarRocks: distinct magento_ref_code in catalog
    const hasDone  = data.has_desc  || 0;   // Postgres rows (per máu)
    const approved = data.approved  || 0;
    const pending  = data.pending   || 0;
    const missing  = Math.max(0, totalSr - hasDone); // never negative

    // Stat cards
    document.getElementById('statTotal').textContent = totalSr.toLocaleString();
    const subEl = document.getElementById('statTotalSub');
    if (subEl) subEl.textContent = `${hasDone.toLocaleString()} code đã có trong DB`;
    document.getElementById('statDone').textContent = hasDone.toLocaleString();
    document.getElementById('statApproved').textContent = approved.toLocaleString();
    document.getElementById('statPending').textContent = pending.toLocaleString();
    document.getElementById('statMissing').textContent = missing.toLocaleString();
    document.getElementById('statMissingClean').textContent = (data.missing_clean_desc || 0).toLocaleString();
    document.getElementById('statMissingTags').textContent = (data.missing_tags || 0).toLocaleString();
    document.getElementById('statHasClean').textContent = (data.has_clean_desc || 0).toLocaleString();
    document.getElementById('statMissingCleanSub').textContent =
      `Đã có ${(hasDone - (data.missing_clean_desc || 0)).toLocaleString()} / ${hasDone.toLocaleString()} bản có format sạch`;

    // Progress = approved / totalPg (not totalSr)
    const approveProgress = hasDone > 0 ? (approved / hasDone * 100).toFixed(1) : 0;
    document.getElementById('statProgress').textContent = approveProgress + '%';
    document.getElementById('progressFill').style.width = approveProgress + '%';
    document.getElementById('btnBatchTags').textContent = `Bơm Tags (Còn ${(data.missing_tags || 0).toLocaleString()} thiếu)`;
    const sizeEl = document.getElementById('statSizeGuide');
    if (sizeEl) sizeEl.textContent = (data.has_size_guide || 0).toLocaleString();
  } catch (e) { console.error('Overview error:', e); }
}

// ═══ Filters ═══
async function loadFilters() {
  try {
    const res = await fetch(`${API}/filters`);
    const data = await res.json();
    if (data.status !== 'success') return;
    const sel = document.getElementById('lineFilter');
    (data.product_lines || []).forEach(l => {
      const opt = document.createElement('option');
      opt.value = l.product_line_vn;
      opt.textContent = `${l.product_line_vn} (${l.cnt})`;
      sel.appendChild(opt);
    });
  } catch (e) {}
}

function resetFilters() {
  document.getElementById('searchInput').value = '';
  document.getElementById('statusFilter').value = '';
  document.getElementById('lineFilter').value = '';
  document.getElementById('tagsFilter').value = '';
  currentPage = 0;
  loadProducts();
}

// ═══ Products List ═══
async function loadProducts() {
  const body = document.getElementById('tableBody');
  body.innerHTML = '<tr><td colspan="10" class="table-loading"><div class="spinner-sm"></div> Đang tải...</td></tr>';

  const search = document.getElementById('searchInput').value.trim();
  const status = document.getElementById('statusFilter').value;
  const line = document.getElementById('lineFilter').value;
  const tagName = document.getElementById('tagsFilter').value.trim();

  const params = new URLSearchParams({ limit: PAGE_SIZE, page: currentPage + 1 });
  if (search) params.set('search', search);
  if (status) params.set('status', status);
  if (line) params.set('product_line', line);
  if (tagName) params.set('tag', tagName);
  
  try {
    const parentUrl = new URL(window.parent.location);
    parentUrl.searchParams.set('p', currentPage + 1);
    window.parent.history.replaceState(null, '', parentUrl.toString());
  } catch(e) {}

  try {
    const res = await fetch(`${API}/list?${params}`);
    const data = await res.json();
    if (data.status !== 'success') throw new Error(data.message);

    currentProducts = data.products || [];
    renderTable(currentProducts);
    renderPagination(data.total);
  } catch (e) {
    body.innerHTML = `<tr><td colspan="10" class="table-loading" style="color:var(--error)">⚠️ ${e.message}</td></tr>`;
  }
}

function renderTable(products) {
  const body = document.getElementById('tableBody');
  if (!products.length) {
    body.innerHTML = '<tr><td colspan="10" class="table-loading">Không tìm thấy sản phẩm nào</td></tr>';
    return;
  }
  body.innerHTML = products.map(p => {
    const descStatus = p.desc_status;
    let statusHtml;
    if (descStatus === 1) {
      statusHtml = '<span class="status-badge done">✅ Đã duyệt</span>';
    } else if (descStatus === 0) {
      statusHtml = '<span class="status-badge pending">⏳ Chờ duyệt</span>';
    } else {
      statusHtml = '<span class="status-badge missing">✕ Chưa có</span>';
    }
    const price = p.sale_price ? Number(p.sale_price).toLocaleString('vi-VN') + '₫' : '—';
    const sold = p.quantity_sold ? Number(p.quantity_sold).toLocaleString() : '0';
    const imgSrc = p.product_image_url_thumbnail || '';
    const imgTag = imgSrc
      ? `<img src="${esc(imgSrc)}" alt="" onerror="this.style.display='none'">`
      : `<div style="width:44px;height:44px;border-radius:6px;background:var(--muted);display:flex;align-items:center;justify-content:center;font-size:16px;">📦</div>`;

    // Use magento_ref_code as the primary key for all actions
    const actionCode = esc(p.magento_ref_code || p.internal_ref_code || '');
    const colorBadge = p.master_color
      ? `<span style="background:#e0f2fe;border:1px solid #7dd3fc;padding:1px 6px;border-radius:8px;font-size:10px;color:#0369a1;">${esc(p.master_color)}</span>`
      : '';
    // Show if magento differs from internal (split variant)
    const isVariant = p.magento_ref_code && p.magento_ref_code !== p.internal_ref_code;
    const codeDisplay = isVariant
      ? `<div class="code" style="font-size:10px;">${esc(p.magento_ref_code || '')} ${colorBadge}</div><div style="font-size:9px;color:#94a3b8;">${esc(p.internal_ref_code || '')}</div>`
      : `<div class="code">${esc(p.magento_ref_code || p.internal_ref_code || '')} ${colorBadge}</div>`;

    return `<tr onclick="openDetail('${actionCode}', '${esc(p.product_name || '')}')">
      <td>
        <div class="product-cell">
          ${imgTag}
          <div class="info">
            <div class="name" title="${esc(p.product_name || '')}">${esc(p.product_name || '—')}</div>
            ${codeDisplay}
          </div>
        </div>
      </td>
      <td>${esc(p.product_line_vn || '—')}</td>
      <td style="max-width:180px; font-size:11px;">
        <div style="display: flex; flex-wrap: wrap; gap: 4px;">
          ${p.tags && p.tags.length > 0 ? p.tags.map(t => `<span style="background:#f1f5f9;border:1px solid #cbd5e1;padding:2px 6px;border-radius:12px;white-space:nowrap;">${esc(t)}</span>`).join('') : '<span style="color:#94a3b8">Chưa có</span>'}
        </div>
      </td>
      <td>${price}</td>
      <td>${sold}</td>
      <td>${statusHtml}</td>
      <td>${p.has_size_guide
        ? '<span style="color:#7c3aed;font-weight:700;font-size:14px" title="\u0110\u00e3 c\u00f3 size guide">\u2714</span>'
        : '<span style="color:#cbd5e1;font-size:14px" title="Ch\u01b0a c\u00f3">\u2014</span>'
      }</td>
      <td style="font-size:11px;color:#64748b;white-space:nowrap">${p.updated_at ? new Date(p.updated_at).toLocaleDateString('vi-VN') + ' ' + new Date(p.updated_at).toLocaleTimeString('vi-VN',{hour:'2-digit',minute:'2-digit'}) : '\u2014'}</td>
      <td>${descStatus >= 0
        ? (descStatus === 1
          ? `<button class="btn btn-sm" style="background:#dc3545;color:#fff;border:none;font-size:11px;padding:4px 10px" onclick="event.stopPropagation();approveRow('${actionCode}',0,this)">✕ Hủy</button>`
          : `<button class="btn btn-sm" style="background:#28a745;color:#fff;border:none;font-size:11px;padding:4px 10px" onclick="event.stopPropagation();approveRow('${actionCode}',1,this)">✓ Duyệt</button>`)
        : '<span style="color:var(--muted-fg);font-size:11px">—</span>'
      }</td>
      <td>
        <div style="display:flex;gap:4px;flex-direction:column;">
          <button class="btn btn-outline-dark btn-sm" onclick="event.stopPropagation();generateSingle('${actionCode}','${esc(p.product_name || '')}',this)">Desc</button>
          <button class="btn btn-outline-dark btn-sm" onclick="event.stopPropagation();generateSingleTags('${actionCode}','${esc(p.product_name || '')}',this)">Tags</button>
          <button class="btn btn-sm" style="background:#7c3aed;color:#fff;border:none;padding:2px 5px;font-size:11px;" onclick="event.stopPropagation();generateSingleSize('${actionCode}','${esc(p.product_name || '')}',this)">📏 Size</button>
          <button class="btn btn-primary btn-sm" style="background:#0ea5e9; border:none; padding:2px 5px;" onclick="event.stopPropagation();openNativeBulkAiModal('${actionCode}')">🤖 Edit</button>
        </div>
      </td>
    </tr>`;
  }).join('');
}

function renderPagination(total) {
  const pages = Math.ceil(total / PAGE_SIZE);
  const el = document.getElementById('pagination');
  if (pages <= 1) { el.innerHTML = ''; return; }
  let html = `<button ${currentPage===0?'disabled':''} onclick="currentPage--;loadProducts()">← Trước</button>`;
  const start = Math.max(0, currentPage - 3);
  const end = Math.min(pages, start + 7);
  for (let i = start; i < end; i++) {
    html += `<button class="${i===currentPage?'active':''}" onclick="currentPage=${i};loadProducts()">${i+1}</button>`;
  }
  html += `<button ${currentPage>=pages-1?'disabled':''} onclick="currentPage++;loadProducts()">Sau →</button>`;
  el.innerHTML = html;
}

// ═══ Generate Single ═══
async function generateSingle(code, name, btn) {
  const ogText = btn.textContent;
  btn.innerHTML = '<span class="spinner-sm"></span>';
  btn.disabled = true;

  try {
    const res = await fetch(`${API}/generate`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ magento_ref_code: code }),
    });
    const data = await res.json();
    if (data.status === 'error') throw new Error(data.message);

    currentDetail = data;
    currentDetailCode = code;
    showDetailPanel(data, name);

    // Update local state and re-render table row
    const p = currentProducts.find(x => x.internal_ref_code === code);
    if (p) {
      p.desc_status = 0; // Chờ duyệt
      renderTable(currentProducts);
    }
    loadOverview(); // Cập nhật lại board thống kê ở trên cùng
  } catch (e) {
    alert('Lỗi: ' + e.message);
  } finally {
    btn.textContent = ogText;
    btn.disabled = false;
  }
}

// ═══ Generate Single Tags ═══
async function generateSingleTags(code, name, btn) {
  const ogText = btn.textContent;
  btn.innerHTML = '<span class="spinner-sm"></span>';
  btn.disabled = true;

  try {
    const res = await fetch(`/api/bulk/generate-tags-single`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ magento_ref_code: code }),
    });
    const data = await res.json();
    if (data.status === 'error') throw new Error(data.message);

    // Update local state and re-render table row
    const p = currentProducts.find(x => x.internal_ref_code === code);
    if (p) {
      if (data.tags) {
         p.tags = data.tags;
      } else {
         alert(data.message || "Đã gửi yêu cầu tạo Tags.");
      }
      renderTable(currentProducts);
    }
  } catch (e) {
    alert('Lỗi: ' + e.message);
  } finally {
    btn.textContent = ogText;
    btn.disabled = false;
  }
}

// ═══ Regenerate from Detail Modal ═══
async function regenerateFromDetail() {
  const code = currentDetailCode;
  if (!code) { alert('Không xác định được mã SP!'); return; }

  const btn = document.getElementById('btnRegenerate');
  const ogText = btn.textContent;
  btn.innerHTML = '<span class="spinner-sm"></span> Đang sinh...';
  btn.disabled = true;
  btn.style.opacity = '0.7';

  // Show loading in Clean tab
  const cleanBody = document.getElementById('detailBodyClean');
  cleanBody.innerHTML = '<div class="table-loading"><div class="spinner-sm"></div> AI đang sinh lại mô tả...<br><span style="font-size:11px;color:var(--muted-fg);">Thông thường mất 5-15 giây</span></div>';

  try {
    // Step 1: Call generate API (this saves to DB automatically)
    const genRes = await fetch(`${API}/generate`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ magento_ref_code: code }),
    });
    const genData = await genRes.json();
    if (genData.status === 'error') throw new Error(genData.message);

    // Step 2: Re-fetch from /saved/ to get proper format (rendered_text, clean_description)
    const savedRes = await fetch(`${API}/saved/${encodeURIComponent(code)}`);
    const savedData = await savedRes.json();

    if (savedData.status === 'success' && savedData.description) {
      const desc = savedData.description;
      currentDetail = {
        phase: desc.phase,
        data: desc.description_data,
        saved: true,
        savedAt: desc.updated_at,
        descStatus: desc.status,
        description: desc
      };
      currentDetailCode = code;

      // Re-render modal with fresh content — stays open!
      showDetailPanel(currentDetail, desc.product_name || document.getElementById('detailTitle').textContent.split('(')[0].trim());
    } else {
      // Fallback: use generate response directly
      currentDetail = genData;
      currentDetailCode = code;
      const name = genData.product?.product_name || document.getElementById('detailTitle').textContent.split('(')[0].trim();
      showDetailPanel(genData, name);
    }

    // Update table row status
    const p = currentProducts.find(x => x.internal_ref_code === code);
    if (p) {
      p.desc_status = 0; // Chờ duyệt (vừa sinh mới)
      renderTable(currentProducts);
    }
    loadOverview();

  } catch (e) {
    cleanBody.innerHTML = `<div style="padding:24px;color:#dc3545;font-weight:600;">❌ Lỗi sinh lại: ${esc(e.message)}</div>`;
  } finally {
    btn.textContent = ogText;
    btn.disabled = false;
    btn.style.opacity = '1';
  }
}

// ═══ Batch Approve Page ═══
async function batchApprovePage() {
  const pendingCodes = currentProducts.filter(p => p.desc_status === 0).map(p => p.internal_ref_code);
  if (pendingCodes.length === 0) {
    alert("Trang hiện tại không có sản phẩm nào 'Chờ duyệt' để duyệt hàng loạt.");
    return;
  }
  if (!confirm(`Xác nhận duyệt hàng loạt ${pendingCodes.length} sản phẩm đang chờ duyệt ở trang này?`)) return;

  const btn = document.getElementById('btnApprovePage');
  const ogText = btn.innerHTML;
  btn.innerHTML = '<div class="spinner-sm"></div> Đang tải...';
  btn.disabled = true;

  try {
    const promises = pendingCodes.map(code => 
      fetch(`${API}/approve`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ internal_ref_code: code, status: 1 }),
      })
    );
    await Promise.all(promises);
    alert(`✅ Đã duyệt thành công ${pendingCodes.length} sản phẩm.`);
    loadProducts();
    loadOverview();
  } catch (e) {
    alert('Lỗi duyệt hàng loạt: ' + e.message);
  } finally {
    btn.innerHTML = ogText;
    btn.disabled = false;
  }
}

// ═══ Approve ALL (toàn bộ chờ duyệt) ═══
async function approveAll() {
  if (!confirm('⚠️ Xác nhận DUYỆT TOÀN BỘ tất cả mô tả đang ở trạng thái "Chờ duyệt"?')) return;

  const btn = document.getElementById('btnApproveAll');
  const ogText = btn.innerHTML;
  btn.innerHTML = '<div class="spinner-sm"></div> Đang duyệt...';
  btn.disabled = true;

  try {
    const resp = await fetch(`${API}/approve-all`, { method: 'POST' });
    const data = await resp.json();
    if (data.status === 'success') {
      alert(`✅ ${data.message}`);
      loadProducts();
      loadOverview();
    } else {
      alert('❌ Lỗi: ' + (data.message || 'Unknown error'));
    }
  } catch (e) {
    alert('❌ Lỗi: ' + e.message);
  } finally {
    btn.innerHTML = ogText;
    btn.disabled = false;
  }
}

async function backfillMissingCleanDescriptions() {
  const summaryRes = await fetch(`${API}/clean-missing-summary`);
  const summary = await summaryRes.json();
  if (summary.status !== 'success') {
    alert('Không lấy được thống kê clean description.');
    return;
  }

  const missing = Number(summary.missing_clean_desc || 0);
  if (missing <= 0) {
    alert('Không có sản phẩm nào thiếu clean description chuẩn.');
    return;
  }

  if (!confirm(`Phát hiện ${missing} sản phẩm đang thiếu hoặc lỗi format clean description.\n\nBấm OK để render lại hàng loạt theo format chuẩn từ description_data hiện có.`)) {
    return;
  }

  const btn = document.getElementById('btnBackfillClean');
  const oldText = btn.innerHTML;
  btn.innerHTML = '<div class="spinner-sm"></div> Đang render...';
  btn.disabled = true;

  try {
    const res = await fetch(`${API}/backfill-clean-description`, { method: 'POST' });
    const data = await res.json();
    if (data.status !== 'success') throw new Error(data.message || 'Unknown error');
    alert(`✅ ${data.message}\nCòn thiếu: ${data.remaining_missing_clean_desc}`);
    loadOverview();
    loadProducts();
  } catch (e) {
    alert('Lỗi backfill clean description: ' + e.message);
  } finally {
    btn.innerHTML = oldText;
    btn.disabled = false;
  }
}
async function batchGeneratePage() {
  const missingCodes = currentProducts.filter(p => p.desc_status === -1).map(p => p.internal_ref_code);
  if (missingCodes.length === 0) {
    alert("Trang hiện tại không có sản phẩm nào 'Chưa có mô tả'. Vui lòng chuyển trang hoặc đổi bộ lọc.");
    return;
  }

  if (!confirm(`Phát hiện ${missingCodes.length} sản phẩm thiếu mô tả ở trang này.\\nĐưa vào hàng đợi tự động sinh AI (Chạy ngầm)?`)) return;

  const btn = document.getElementById('btnBatch');
  const ogText = btn.innerHTML;
  btn.innerHTML = '<div class="spinner-sm"></div> Đang gửi...';
  btn.disabled = true;

  try {
    const res = await fetch(`${API}/batch-generate`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ internal_ref_codes: missingCodes })
    });
    const data = await res.json();
    if (data.status === 'error') throw new Error(data.message);

    alert(data.message);
    startBatchPolling();
    // Refresh table immediately to not click again
    loadProducts();
  } catch (e) {
    alert('Lỗi chạy hàng loạt: ' + e.message);
  } finally {
    btn.innerHTML = ogText;
    btn.disabled = false;
  }
}

// ═══ Batch Generate All ═══
async function batchGenerateAll() {
  if (!confirm(`Hệ thống sẽ tự động quét TẤT CẢ sản phẩm thiếu mô tả trong database (tối đa 500 SP/lần) và đưa vào hàng đợi sinh AI chạy ngầm.\\n\\nBạn có chắc chắn muốn chạy không?`)) return;

  const btn = document.getElementById('btnBatchAll');
  const ogText = btn.innerHTML;
  btn.innerHTML = '<div class="spinner-sm"></div> Đang gửi...';
  btn.disabled = true;

  try {
    const res = await fetch(`${API}/batch-generate-all`, {
      method: 'POST'
    });
    const data = await res.json();
    if (data.status === 'error') throw new Error(data.message);

    alert(data.message);
    startBatchPolling();
    loadProducts();
    loadOverview();
  } catch (e) {
    alert('Lỗi chạy toàn bộ: ' + e.message);
  } finally {
    btn.innerHTML = ogText;
    btn.disabled = false;
  }
}

// ═══ Batch Tracking Polling ═══
let batchPollInterval = null;

// ═══ NATIVE BULK AI EDIT ═══
let currentBulkAiTarget = [];
let currentBulkLineTarget = "";

function openNativeBulkAiModal(singleSku = null) {
  if (singleSku) {
      currentBulkAiTarget = [singleSku];
      const p = currentProducts.find(x => x.internal_ref_code === singleSku);
      currentBulkLineTarget = p ? p.product_line_vn : '';
      
      document.getElementById('lblBulkAiCount').innerHTML = `<strong>1 sản phẩm</strong> (SKU: ${singleSku})`;
      
      let lineOption = '';
      if (currentBulkLineTarget) {
          lineOption = `<label style="cursor:pointer; display:block; margin-top:6px;"><input type="radio" name="scopeTarget" value="line"> Áp dụng cho TẤT CẢ sản phẩm thuộc dòng: <strong>${currentBulkLineTarget}</strong></label>`;
      }
      
      document.getElementById('scopeContainer').innerHTML = `
        <div style="background:#eff6ff; padding:12px; border-radius:6px; border:1px solid #bfdbfe; margin-bottom:15px;">
           <div style="font-weight:bold; font-size:13px; margin-bottom:8px; color:#1e40af;">🎯 Phạm vi áp dụng:</div>
           <label style="cursor:pointer; display:block;"><input type="radio" name="scopeTarget" value="sku" checked> Chỉ sửa DUY NHẤT 1 mã: <strong>${singleSku}</strong></label>
           ${lineOption}
        </div>
      `;
  } else {
      if (!currentProducts || currentProducts.length === 0) {
        alert("Trang hiện tại không có sản phẩm nào để xử lý!");
        return;
      }
      currentBulkAiTarget = currentProducts.map(p => p.internal_ref_code);
      currentBulkLineTarget = "";
      document.getElementById('lblBulkAiCount').innerHTML = `<strong>${currentBulkAiTarget.length} sản phẩm</strong> đang hiển thị trên trang này`;
      document.getElementById('scopeContainer').innerHTML = ''; // Hide scope container for page-level bulk
  }

  // Try to load dynamic fields if possible, or fallback to default html opts
  fetch('/api/bulk/fields').then(r => r.json()).then(d => {
      if (d.status === 'success') {
          const sel = document.getElementById('nativeBulkAiField');
          sel.innerHTML = '';
          for (const [key, label] of Object.entries(d.fields)) {
              if (key === 'huong_dan_size') sel.innerHTML += `<option value="${key}" selected>${label}</option>`;
              else sel.innerHTML += `<option value="${key}">${label}</option>`;
          }
      }
  }).catch(() => {});
  
  document.getElementById('nativeBulkAiModal').style.display = 'flex';
}

async function execNativeBulkAi() {
  const field = document.getElementById('nativeBulkAiField').value;
  const mode = document.getElementById('nativeBulkAiMode').value;
  const instruction = document.getElementById('nativeBulkAiInstruction').value.trim();

  if (!instruction) {
    alert("⚠️ Vui lòng nhập hướng dẫn hoặc paste bảng size thô cho AI!");
    return;
  }

  // Determine scope
  let codes = [...(currentBulkAiTarget || [])];
  let target_line = null;
  const scopeRadio = document.querySelector('input[name="scopeTarget"]:checked');
  if (scopeRadio && scopeRadio.value === 'line') {
      target_line = currentBulkLineTarget;
      codes = []; // Force backend to use target_line to resolve codes
  }

  if (codes.length === 0 && !target_line) {
      alert("⚠️ Không có sản phẩm nào được chọn!");
      return;
  }

  const btn = document.getElementById('btnRunNativeBulkAi');
  const ogText = btn.innerHTML;
  btn.innerHTML = '<div class="spinner-sm"></div> Đang gửi lệnh...';
  btn.disabled = true;

  try {
      const resp = await fetch('/api/bulk/ai-edit', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ codes, target_field: field, instruction, mode, target_line }),
      });
      const data = await resp.json();
      
      if (data.status === 'success') {
          document.getElementById('nativeBulkAiModal').style.display = 'none';
          alert(`✅ ${data.message}\\nTiến trình sẽ chạy dưới nền (Background Worker)`);
          
          // Poll ui in background
          setTimeout(() => {
              fetch(`/api/bulk/ai-edit-status`)
                .then(r => r.json())
                .then(s => {
                  if (s.is_running && s.total > 0) startAiEditBatchPolling();
                });
          }, 1500);
      } else {
          alert(`❌ Lỗi: ${data.message}`);
      }
  } catch (e) {
      alert(`❌ Lỗi gọi API: ${e.message}`);
  } finally {
      btn.innerHTML = ogText;
      btn.disabled = false;
  }
}

// Custom poller for AI Edit Queue (mapped to Tag polling tracking UI just to show running status)
let aiEditPollInterval = null;
function startAiEditBatchPolling() {
  if (aiEditPollInterval) return; 
  document.getElementById('tagsTrackingBox').style.display = 'flex'; // Reuse Tags box UI
  
  aiEditPollInterval = setInterval(async () => {
    try {
      const res = await fetch(`/api/bulk/ai-edit-status`);
      const data = await res.json();
      
      if (!data.is_running) {
        clearInterval(aiEditPollInterval);
        aiEditPollInterval = null;
        document.getElementById('tagsTrackTitle').innerText = '✅ Hoàn tất Bulk AI Edit!';
        document.getElementById('tagsTrackFill').style.background = '#059669';
        setTimeout(() => {
          document.getElementById('tagsTrackingBox').style.display = 'none';
          loadProducts(); 
        }, 5000);
        return;
      }
      
      const pct = data.total > 0 ? Math.round((data.done / data.total) * 100) : 0;
      document.getElementById('tagsTrackTitle').innerText = 'Hệ thống đang Bulk AI Edit (Sửa trường)...';
      document.getElementById('tagsTrackFill').style.background = '#2563eb';
      document.getElementById('tagsTrackText').innerText = `${data.done} / ${data.total} (${pct}%)`;
      document.getElementById('tagsTrackFill').style.width = pct + '%';
      document.getElementById('tagsTrackCode').innerText = data.current_name ? `→ ${data.current_name}` : '—';
      document.getElementById('tagsTrackErrors').innerText = data.errors || 0;
      
    } catch(e) {}
  }, 2000);
}


function startBatchPolling() {
  if (batchPollInterval) return; // Already polling
  document.getElementById('batchTrackingBox').style.display = 'flex';
  batchPollInterval = setInterval(async () => {
    try {
      const res = await fetch(`${API}/batch-status`);
      const data = await res.json();
      
      if (!data.progress || !data.progress.is_running) {
        clearInterval(batchPollInterval);
        batchPollInterval = null;
        document.getElementById('batchTrackTitle').innerText = '✅ Hoàn tất sinh AI hàng loạt!';
        document.getElementById('batchTrackFill').style.background = '#10b981';
        setTimeout(() => {
          document.getElementById('batchTrackingBox').style.display = 'none';
          loadOverview();
          loadProducts();
        }, 5000);
        return;
      }
      
      const prog = data.progress;
      const pct = Math.round((prog.done / prog.total) * 100) || 0;
      document.getElementById('batchTrackTitle').innerText = 'Hệ thống đang chạy AI hàng loạt...';
      document.getElementById('batchTrackFill').style.background = '#0ea5e9';
      document.getElementById('batchTrackText').innerText = `${prog.done} / ${prog.total} (${pct}%)`;
      document.getElementById('batchTrackFill').style.width = pct + '%';
      document.getElementById('batchTrackCode').innerText = prog.current_code || '—';
      document.getElementById('batchTrackErrors').innerText = prog.errors || 0;
      
    } catch(e) {
      console.error("Lỗi poll status:", e);
    }
  }, 2000); // poll every 2 seconds
}

// Check status on mount just in case a batch is already running
setTimeout(() => {
  fetch(`${API}/batch-status`)
    .then(r => r.json())
    .then(s => {
      if (s.is_running && s.progress) startBatchPolling();
      else if (s.progress && s.progress.is_running) startBatchPolling();
    })
    .catch(()=>{});
    
  fetch(`/api/bulk/tags-batch-status`)
    .then(r => r.json())
    .then(s => {
      if (s.progress && s.progress.is_running) startTagsBatchPolling();
    })
    .catch(()=>{});
}, 1000);

// ═══ Batch Generate TAGS ═══
async function batchGenerateTags() {
  if (!confirm(`Hệ thống sẽ chạy AI đọc toàn bộ clean_description (mô tả chuẩn) để tự động móc Tags (đi chơi, đi làm, thể thao...).\\nChỉ quét 500 SP đang trống tags.\\n\\nBạn có chắc chắn muốn bắt đầu?`)) return;

  const btn = document.getElementById('btnBatchTags');
  const ogText = btn.innerHTML;
  btn.innerHTML = '<div class="spinner-sm"></div> Đang gửi...';
  btn.disabled = true;

  try {
    const res = await fetch(`/api/bulk/batch-generate-tags`, { method: 'POST' });
    const data = await res.json();
    if (data.status === 'error') throw new Error(data.message);

    alert(data.message);
    startTagsBatchPolling();
  } catch (e) {
    alert('Lỗi bơm tags hàng loạt: ' + e.message);
  } finally {
    btn.innerHTML = ogText;
    btn.disabled = false;
  }
}

let tagsPollInterval = null;
function startTagsBatchPolling() {
  if (tagsPollInterval) return; 
  document.getElementById('tagsTrackingBox').style.display = 'flex';
  
  tagsPollInterval = setInterval(async () => {
    try {
      const res = await fetch(`/api/bulk/tags-batch-status`);
      const data = await res.json();
      
      if (!data.progress || !data.progress.is_running) {
        clearInterval(tagsPollInterval);
        tagsPollInterval = null;
        document.getElementById('tagsTrackTitle').innerText = '✅ Hoàn tất Auto-Tagging!';
        document.getElementById('tagsTrackFill').style.background = '#059669';
        setTimeout(() => {
          document.getElementById('tagsTrackingBox').style.display = 'none';
          loadProducts(); // refresh list to show new tags
        }, 5000);
        return;
      }
      
      const prog = data.progress;
      const pct = Math.round((prog.done / prog.total) * 100) || 0;
      document.getElementById('tagsTrackTitle').innerText = 'Hệ thống đang Auto-Tagging hàng loạt...';
      document.getElementById('tagsTrackFill').style.background = '#10b981';
      document.getElementById('tagsTrackText').innerText = `${prog.done} / ${prog.total} (${pct}%)`;
      document.getElementById('tagsTrackFill').style.width = pct + '%';
      document.getElementById('tagsTrackCode').innerText = prog.current_code || '—';
      document.getElementById('tagsTrackErrors').innerText = prog.errors || 0;
      
    } catch(e) {
      console.error("Lỗi poll status tags:", e);
    }
  }, 2000);
}

// ═══ Detail Panel ═══
async function openDetail(code, name) {
  // Show loading state
  document.getElementById('detailTitle').textContent = name || 'Đang tải...';
  document.getElementById('detailBodyClean').innerHTML = '<div class="table-loading"><div class="spinner-sm"></div> Đang tải...</div>';
  document.getElementById('detailOverlay').classList.add('open');

  // Try to load saved description first
  try {
    const res = await fetch(`${API}/saved/${encodeURIComponent(code)}`);
    if (res.ok) {
      const saved = await res.json();
      if (saved.status === 'success' && saved.description) {
        const desc = saved.description;
        currentDetail = {
          phase: desc.phase,
          data: desc.description_data,
          saved: true,
          savedAt: desc.updated_at,
          descStatus: desc.status,
          description: desc
        };
        currentDetailCode = code;
        showDetailPanel(currentDetail, desc.product_name || name);
        return;
      }
    }
  } catch (e) { /* not found, will generate */ }

  // No saved description → generate new
  closeDetail();
  generateSingle(code, name, { textContent: '', innerHTML: '', disabled: false, closest: () => null });
}

function closeDetail() {
  document.getElementById('detailOverlay').classList.remove('open');
  // Clean up localStorage cache for this product (DB is source of truth)
  if (currentDetailCode) {
    try { localStorage.removeItem(`desc_cache_${currentDetailCode}`); } catch(e) {}
  }
}

function showDetailPanel(data, name) {
  const d = data.description?.description_data || data.data || {};
  const c = data.description || {};
  
  const title = name ? `${name} <span style="font-weight:400;color:var(--muted-fg);font-size:13px">(${c.internal_ref_code || currentDetailCode})</span>` : (c.internal_ref_code || currentDetailCode || 'Chi tiết');
  document.getElementById('detailTitle').innerHTML = title;

  // 1. Clean Tab - Render Format Đẹp Đẹp
  const cleanBody = document.getElementById('detailBodyClean');
  
  // Render "Dàn trang (Chuẩn)" — Premium structured view từ description_data
  const descData = d || {};
  const productName = name || descData['ten_san_pham'] || c.internal_ref_code || '';

  function _fv(v) {
    if (!v || v === 'null' || v === 'undefined') return '';
    return String(v).trim();
  }
  function _row(label, key, value) {
    const v = _fv(value);
    if (!v) return '';
    return `<div class="dd-row"><span class="dd-label">${label}</span><span class="dd-value" id="dantrang-val-${key}" contenteditable="true" title="Click để chỉnh sửa" style="outline:none;cursor:text;border-bottom:1px dashed transparent;border-radius:3px;padding:1px 4px;" onfocus="this.style.background='#fffbeb';this.style.borderColor='var(--primary)'" onblur="this.style.background='';this.style.borderColor='transparent'">${esc(v)}</span></div>`;
  }
  function _bullets(v) {
    if (!_fv(v)) return '';
    const items = _fv(v).split(/[\n•·]+/).map(x => x.trim()).filter(Boolean);
    if (!items.length) return '';
    return items.map(i => `<li>${esc(i)}</li>`).join('');
  }

  const sections = [];

  // ── THÔNG TIN CƠ BẢN ──
  const basicFields = [
    ['ten_san_pham','Tên sản phẩm'], ['tagline','Tagline'], ['mo_ta_chinh','Mô tả chính'],
    ['phong_cach','Phong cách'], ['tags','Tags'],
  ];
  let basicHtml = basicFields.map(([k,l]) => _row(l, descData[k])).join('');
  if (basicHtml) sections.push({ emoji:'🏷️', title:'THÔNG TIN CƠ BẢN', body: basicHtml });

  // ── CHẤT LIỆU & BẢO QUẢN ──
  let matHtml = [_row('Chất liệu', descData['chat_lieu']), _row('Tính năng vải', descData['tinh_nang_vai']), _row('Hướng dẫn bảo quản', descData['huong_dan_bao_quan'])].join('');
  if (matHtml) sections.push({ emoji:'🌿', title:'CHẤT LIỆU & BẢO QUẢN', body: matHtml });

  // ── ĐỐI TƯỢNG ──
  let targetHtml = [_row('Độ tuổi', 'do_tuoi', descData['do_tuoi']), _row('Giới tính', 'gioi_tinh', descData['gioi_tinh']), _row('Lối sống', 'loi_song', descData['loi_song']), _row('Tính cách', 'tinh_cach', descData['tinh_cach'])].join('');
  if (targetHtml) sections.push({ emoji:'👤', title:'ĐỐI TƯỢNG', body: targetHtml });

  // ── DỊP MẶC & STYLING ──
  const dipMac = _fv(descData['dip_mac']);
  const phoi = _fv(descData['phoi_do']);
  const nguyen = _fv(descData['nguyen_tac_phoi_do']);
  const layer = _fv(descData['layer'] || descData['goi_y_layer']);
  const mua = _fv(descData['mua_phu_hop']);
  let styleHtml = '';
  if (dipMac) styleHtml += `<div class="dd-row"><span class="dd-label">Dịp mặc</span><span class="dd-value"><ul class="dd-bullets">${_bullets(dipMac)}</ul></span></div>`;
  if (phoi)   styleHtml += `<div class="dd-row"><span class="dd-label">Gợi ý phối đồ</span><span class="dd-value"><ul class="dd-bullets">${_bullets(phoi)}</ul></span></div>`;
  if (nguyen) styleHtml += `<div class="dd-row"><span class="dd-label">Nguyên tắc phối</span><span class="dd-value">${esc(nguyen)}</span></div>`;
  if (layer)  styleHtml += `<div class="dd-row"><span class="dd-label">Gợi ý layering</span><span class="dd-value">${esc(layer)}</span></div>`;
  if (mua)    styleHtml += `<div class="dd-row"><span class="dd-label">Mùa phù hợp</span><span class="dd-value">${esc(mua)}</span></div>`;
  if (styleHtml) sections.push({ emoji:'👗', title:'DỊP MẶC & STYLING', body: styleHtml });

  // ── FAQ ──
  const faq = descData['faq'] || descData['FAQQ'] || '';
  if (_fv(faq)) {
    const pairs = _fv(faq).split(/Q:|💬/).map(x=>x.trim()).filter(Boolean);
    let faqHtml = '';
    pairs.forEach(pair => {
      const [q, ...aParts] = pair.split(/A:|→/);
      if (q) faqHtml += `<div class="dd-faq-q">💬 ${esc(q.trim())}</div>`;
      if (aParts.length) faqHtml += `<div class="dd-faq-a">${esc(aParts.join('').trim())}</div>`;
    });
    if (faqHtml) sections.push({ emoji:'❓', title:'FAQ', body: faqHtml });
  }

  // ── HỖ TRỢ BÁN HÀNG ──
  const hookQC = _fv(descData['hook_quang_cao']);
  const crossSell = _fv(descData['cross_sell'] || descData['upsell']);
  const sizeGuide = _fv(descData['huong_dan_size'] || descData['size_guide']);
  let salesHtml = '';
  if (hookQC)    salesHtml += `<div class="dd-highlight">${esc(hookQC)}</div>`;
  if (crossSell) salesHtml += `<div class="dd-row"><span class="dd-label">Cross-sell</span><span class="dd-value">${esc(crossSell)}</span></div>`;
  if (sizeGuide) salesHtml += `<div class="dd-row"><span class="dd-label">Hướng dẫn size</span><span class="dd-value"><ul class="dd-bullets">${_bullets(sizeGuide)}</ul></span></div>`;
  if (salesHtml) sections.push({ emoji:'🛒', title:'HỖ TRỢ BÁN HÀNG', body: salesHtml });

  // Fallback nếu không có data struct → dùng rendered_text
  const hasSections = sections.some(s => s.body);
  let finalHtml = '';

  if (hasSections) {
    finalHtml = `
      <div class="dd-product-name">${esc(productName).toUpperCase()}</div>
      ${sections.map(s => `
        <div class="dd-section">
          <div class="dd-section-header"><span class="dd-emoji">${s.emoji}</span> ${s.title}</div>
          <div class="dd-section-body">${s.body}</div>
        </div>
      `).join('')}
    `;
  } else if (c.rendered_text) {
    let html = c.rendered_text;
    if (!html.includes('<h2') && !html.includes('<div') && !html.includes('<li')) {
      let text = esc(html);
      text = text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
      text = text.replace(/\n/g, '<br>');
      html = text;
    }
    finalHtml = html;
  } else {
    finalHtml = '<p style="color:var(--muted-fg);padding:24px;">Chưa có nội dung từ AI.</p>';
  }

  cleanBody.innerHTML = `
    <style>
      .dd-product-name{font-size:20px;font-weight:800;text-align:center;letter-spacing:.06em;color:#0b1c44;margin:0 0 20px;padding-bottom:16px;border-bottom:2px solid #e5e7eb}
      .dd-section{margin-bottom:20px;border:1px solid #e5e7eb;border-radius:10px;overflow:hidden;background:#fff}
      .dd-section-header{display:flex;align-items:center;gap:8px;padding:10px 16px;background:linear-gradient(135deg,#f8fafc,#f1f5f9);font-weight:700;font-size:12px;letter-spacing:.08em;color:#1e3a5f;border-bottom:1px solid #e5e7eb;text-transform:uppercase}
      .dd-emoji{font-size:16px}
      .dd-section-body{padding:14px 16px}
      .dd-row{display:flex;gap:12px;margin-bottom:10px;line-height:1.5;font-size:13.5px}
      .dd-label{font-weight:700;color:#374151;min-width:140px;flex-shrink:0}
      .dd-value{color:#4b5563;flex:1}
      .dd-bullets{margin:0;padding-left:18px}
      .dd-bullets li{margin-bottom:4px;font-size:13.5px;color:#4b5563}
      .dd-highlight{background:linear-gradient(135deg,#eff6ff,#dbeafe);border-left:3px solid #3b82f6;padding:10px 14px;border-radius:6px;font-size:13.5px;color:#1e40af;font-style:italic;margin-bottom:10px}
      .dd-faq-q{font-weight:700;font-size:13.5px;color:#374151;margin-bottom:4px;margin-top:12px}
      .dd-faq-q:first-child{margin-top:0}
      .dd-faq-a{font-size:13.5px;color:#4b5563;padding-left:16px;border-left:3px solid #10b981;margin-bottom:8px}
    </style>
    <div id="cleanTextEditor"
      style="padding:24px;font-family:'Inter',system-ui,sans-serif;min-height:200px">
      ${finalHtml}
    </div>
  `;

  // 2. We no longer render editBody here! Instead, we set up variables 
  // so that if the user clicks "Chỉnh sửa ở Tab Clean Data", it knows what to load.
  window.currentDetailDataForCleanTab = data;
  window.currentDetailNameForCleanTab = name;

  // 3. Fields Tab
  const fieldsBody = document.getElementById('detailBodyFields');
  let fHtml = '<div style="padding: 24px;">';
  for (const [k, v] of Object.entries(d)) {
    fHtml += `
      <div style="margin-bottom: 16px; padding: 12px; background: #f9fafb; border-radius: 8px; border: 1px solid #e5e7eb;">
        <div style="display:flex; justify-content:space-between; margin-bottom:8px;">
           <strong style="color:var(--primary); font-size:14px;">${esc(k)}</strong>
           <button class="btn btn-sm" style="background:#e0e7ff; color:#4f46e5; border:none; border-radius:4px; font-size:12px; font-weight:600; cursor:pointer;" onclick="rewriteField('${c.internal_ref_code || currentDetailCode}', '${esc(k)}', this)">✨ AI Viết Lại</button>
        </div>
        <div id="field-val-${k}" style="font-size: 14px; color: #374151; white-space: pre-wrap;">${esc(v)}</div>
      </div>
    `;
  }
  fHtml += '</div>';
  fieldsBody.innerHTML = fHtml;

  // 3.5 Embed (Clean Descripts) Tab
  const embedBody = document.getElementById('detailPreEmbed');
  const rawCleanDesc = c.clean_description || c.rendered_text || 'Chưa có clean description cho sản phẩm này.';
  embedBody.innerText = rawCleanDesc;

  const isApproved = c.status === 1 || data.descStatus === 1;
  if (!isApproved) {
     embedBody.contentEditable = "true";
     embedBody.style.border = "1px solid #10b981";
     embedBody.style.cursor = "text";
     embedBody.title = "Bạn có thể chỉnh sửa trực tiếp hoặc bôi đen văn bản để gọi AI Codex";
  } else {
     embedBody.contentEditable = "false";
     embedBody.style.border = "1px dashed #d1d5db";
     embedBody.style.cursor = "default";
     embedBody.title = "Đã duyệt - Bạn không thể sửa (Hãy nhấn Hủy duyệt nếu muốn sửa)";
  }

  // 4. Raw Tab
  const rawBody = document.getElementById('detailPreRaw');
  rawBody.textContent = JSON.stringify(d, null, 2);

  document.getElementById('detailOverlay').classList.add('open');
  switchDetailTab('clean');

  // Show/hide approve buttons
  const btnApprove = document.getElementById('btnApprove');
  const btnReject = document.getElementById('btnReject');
  
  if (c.saved_at || data.saved) {
    btnApprove.style.display = isApproved ? 'none' : '';
    btnReject.style.display = isApproved ? '' : 'none';
  } else {
    // Just generated -> waiting for save
    btnApprove.style.display = '';
    btnReject.style.display = 'none';
  }
}

let activeDetailTab = 'clean';
function switchDetailTab(tabId) {
  // Reset all
  document.querySelectorAll('.tab-btn').forEach(btn => {
    btn.classList.remove('active');
    btn.style.color = 'var(--muted-fg)';
    btn.style.borderColor = 'transparent';
  });
  
  if(document.getElementById('detailBodyClean')) document.getElementById('detailBodyClean').style.display = 'none';
  if(document.getElementById('detailBodyFields')) document.getElementById('detailBodyFields').style.display = 'none';
  if(document.getElementById('detailBodyEmbed')) document.getElementById('detailBodyEmbed').style.display = 'none';
  if(document.getElementById('detailBodyRaw')) document.getElementById('detailBodyRaw').style.display = 'none';
  
  document.querySelector('.detail-panel').style.background = 'var(--card)';

  const activeTab = document.getElementById(tabId === 'clean' ? 'dTabClean' : 'dTabEmbed');
  if (activeTab) {
    activeTab.classList.add('active');
    activeTab.style.color = 'var(--primary)';
    activeTab.style.borderColor = 'var(--primary)';
  }

  if (tabId === 'clean') {
    document.getElementById('detailBodyClean').style.display = 'block';
    const _cleanEl = document.getElementById('detailBodyClean'); if(_cleanEl) _cleanEl.scrollTop = 0;
    document.getElementById('btnSavePopupText').style.display = 'inline-block';
  } else if (tabId === 'fields') {
    document.getElementById('detailBodyFields').style.display = 'block';
    document.getElementById('btnSavePopupText').style.display = 'none';
  } else if (tabId === 'embed') {
    document.getElementById('detailBodyEmbed').style.display = 'block';
    document.getElementById('btnSavePopupText').style.display = 'none';
  } else if (tabId === 'raw') {
    document.getElementById('detailBodyRaw').style.display = 'block';
    document.getElementById('btnSavePopupText').style.display = 'none';
  }
}

async function rewriteField(code, key, btn) {
  if(!code || !key) return;
  const vDiv = document.getElementById(`field-val-${key}`);
  
  btn.innerHTML = '<span class="spinner-sm" style="border-width:2px; width:12px; height:12px; border-color:#4f46e5 transparent transparent transparent;"></span> ...';
  btn.disabled = true;
  vDiv.style.opacity = '0.5';
  
  try {
    const res = await fetch(`${API}/saved/${encodeURIComponent(code)}/rewrite-field`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ field_key: key })
    });
    const data = await res.json();
    if (data.status === 'success') {
      vDiv.innerText = data.new_value;
      
      // Update local cache
      if(window.currentDetailDataForCleanTab && window.currentDetailDataForCleanTab.data) {
        window.currentDetailDataForCleanTab.data[key] = data.new_value;
      }
      if(window.currentDetailDataForCleanTab && window.currentDetailDataForCleanTab.description) {
        window.currentDetailDataForCleanTab.description.rendered_text = data.clean_description;
      }
      
      btn.innerHTML = '✅ OK';
      setTimeout(() => { btn.innerHTML = '✨ AI Viết Lại'; btn.disabled = false; }, 2000);
      
      // Attempt to re-render clean html implicitly
      const cleanEditor = document.getElementById('cleanTextEditor');
      if (cleanEditor && cleanEditor.innerHTML && !cleanEditor.innerHTML.trim().includes('<h2')) {
          // If pure text, let's just do a tiny logic to refresh the popup if they switch tabs
          // No big deal if not, they can refresh page.
      }
    } else {
      throw new Error(data.message || 'Lỗi');
    }
  } catch(e) {
    alert("Lỗi: " + e.message);
    btn.innerHTML = '✨ AI Viết Lại';
    btn.disabled = false;
  }
  vDiv.style.opacity = '1';
}

// Helper for formatting fake strings temporarily
function StrReplaceFake(str) { 
  return str; // If need markdown replacement later
}

// --- Clean Data Tab Logic ---
function goToCleanData() {
  closeDetail();
  switchTab('cleanData');
  
  document.getElementById('cleanDataSearch').value = currentDetailCode || '';
  renderCleanDataForm();
}

async function loadCleanDataForInput() {
  const code = document.getElementById('cleanDataSearch').value.trim();
  if(!code) return alert("Nhập mã sản phẩm!");
  
  document.getElementById('cleanDataEditor').innerHTML = '<div class="table-loading"><div class="spinner-sm"></div> Đang tải...</div>';
  document.getElementById('cleanDataEditor').style.display = 'block';
  document.getElementById('cleanDataEmpty').style.display = 'none';
  
  try {
    const res = await fetch(`${API}/saved/${encodeURIComponent(code)}`);
    if (res.ok) {
      const saved = await res.json();
      if (saved.status === 'success' && saved.description) {
        window.currentDetailDataForCleanTab = { 
          data: saved.description.description_data,
          description: saved.description
        };
        window.currentDetailNameForCleanTab = saved.description.product_name || `Sản phẩm ${code}`;
        currentDetailCode = code;
        renderCleanDataForm();
        return;
      }
    }
    alert("Không tìm thấy dữ liệu cho mã này. Hãy generate trước ở tab Sản phẩm.");
    document.getElementById('cleanDataEditor').style.display = 'none';
    document.getElementById('cleanDataEmpty').style.display = 'block';
  } catch (e) { alert("Lỗi khi tải dữ liệu"); }
}

function renderCleanDataForm() {
  const data = window.currentDetailDataForCleanTab;
  const name = window.currentDetailNameForCleanTab;
  if(!data) return;
  
  document.getElementById('cleanDataEmpty').style.display = 'none';
  document.getElementById('cleanDataEditor').style.display = 'block';
  document.getElementById('cleanDataTitle').style.display = 'block';
  document.getElementById('btnSaveCleanData').style.display = 'inline-block';
  
  const c = data.description || {};
  const d = data.description?.description_data || data.data || {};
  document.getElementById('cleanDataTitle').innerHTML = `Đang chỉnh sửa: <span style="color:#000;">${name || c.internal_ref_code || currentDetailCode}</span> (${currentDetailCode})`;
  
  const editBody = document.getElementById('cleanDataEditor');
  let editHtml = `<div style="display:flex; flex-direction:column; gap:16px;">`;
  
  const orderedKeys = ['ten_san_pham', 'tagline', 'mo_ta_chinh', 'phong_cach', 'chat_lieu', 'tinh_nang_vai', 'huong_dan_bao_quan'];
  const allKeys = Object.keys(d);
  const remainingKeys = allKeys.filter(k => !orderedKeys.includes(k)).sort();
  const sortedKeys = [...orderedKeys.filter(k => allKeys.includes(k)), ...remainingKeys];
  
  sortedKeys.forEach(k => {
    editHtml += `
      <div style="background:#fff; border:1px solid #e5e7eb; border-radius:8px; padding:16px;">
        <label style="display:block; font-size:13px; font-weight:700; color:var(--primary); margin-bottom:8px; text-transform:uppercase;">${esc(k)} <button onclick="deleteField('${k}')" style="float:right; border:none; background:none; color:var(--warn); cursor:pointer; font-size:11px; font-weight:bold;">✕ Xóa trường này</button></label>
        <textarea id="editField_${k}" data-key="${k}" style="width:100%; box-sizing:border-box; border:1px solid #d1d5db; border-radius:6px; padding:10px; font-size:14px; font-family:inherit; min-height:60px; line-height:1.5; resize:vertical;">${esc(d[k] || '')}</textarea>
      </div>`;
  });
  
  editHtml += `
      <div style="background:#f0f9ff; border:2px dashed #bae6fd; border-radius:8px; padding:16px; margin-top:12px;">
        <label style="display:block; font-size:13px; font-weight:700; color:#0369a1; margin-bottom:10px;">➕ BỔ SUNG TRƯỜNG MỚI</label>
        <div style="display:flex; gap:10px;">
          <input type="text" id="newFieldKey" placeholder="Tên key (vd: dac_diem_noi_bat)" style="flex:1; border:1px solid #bae6fd; border-radius:6px; padding:10px; font-size:14px; outline:none;">
          <input type="text" id="newFieldValue" placeholder="Nội dung" style="flex:2; border:1px solid #bae6fd; border-radius:6px; padding:10px; font-size:14px; outline:none;">
          <button class="btn btn-sm" style="background:#0284c7;color:#fff;border:none;font-weight:bold;padding:0 20px;" onclick="addNewField()">Thêm</button>
        </div>
      </div>
  </div>`;
  editBody.innerHTML = editHtml;
}

function getSafeDetailData() {
  if (window.currentDetailDataForCleanTab) {
    if (window.currentDetailDataForCleanTab.description && window.currentDetailDataForCleanTab.description.description_data) return window.currentDetailDataForCleanTab.description.description_data;
    if (window.currentDetailDataForCleanTab.data) return window.currentDetailDataForCleanTab.data;
  }
  return {};
}

function gatherInputsIntoData() {
  const inputs = document.querySelectorAll('#cleanDataEditor textarea[data-key]');
  const d = getSafeDetailData();
  inputs.forEach(el => { d[el.getAttribute('data-key')] = el.value; });
  return d;
}

function deleteField(key) {
  if (!confirm(`Xóa trường [${key}]?`)) return;
  const d = gatherInputsIntoData();
  delete d[key];
  renderCleanDataForm();
}

function addNewField() {
  const k = document.getElementById('newFieldKey').value.trim();
  const v = document.getElementById('newFieldValue').value.trim();
  if (!k) return alert('Phải nhập Tên key!');
  const safe_k = k.toLowerCase().replace(/[^a-z0-9_]/g, '_');
  
  const d = gatherInputsIntoData();
  d[safe_k] = v;
  renderCleanDataForm();
}

async function saveDetailEdit() {
  if (!currentDetailCode) return;
  const btn = document.getElementById('btnSaveCleanData');
  const orgText = btn.textContent;
  btn.textContent = 'Đang lưu...';
  btn.disabled = true;
  
  try {
    const newData = gatherInputsIntoData();

    // Send update request
    const res = await fetch(`${API}/saved/${currentDetailCode}/update`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ description_data: newData })
    });
    const data = await res.json();
    if (data.status === 'error') throw new Error(data.message);
    
    btn.textContent = '✓ Lưu thành công!';

    // Re-fetch fresh data from server to refresh in-memory state correctly
    // (avoids shared-reference mutation bugs that made the form appear blank)
    try {
      const freshRes = await fetch(`${API}/saved/${encodeURIComponent(currentDetailCode)}`);
      const freshJson = await freshRes.json();
      if (freshJson.status === 'success' && freshJson.description) {
        window.currentDetailDataForCleanTab = {
          data: freshJson.description.description_data,
          description: freshJson.description,
        };
        renderCleanDataForm();
      }
    } catch (_) { /* non-critical — form already saved, just show stale data */ }

    // Refresh main table
    loadProducts();
    loadOverview();

    setTimeout(() => { btn.textContent = orgText; btn.disabled = false; }, 2000);

  } catch (e) {
    alert('Lỗi lưu thay đổi: ' + e.message);
    btn.textContent = '💾 Lưu';
    btn.disabled = false;
  }
}


function copyDetailJson() {
  if (!currentDetail) return;
  const text = currentDetail.description?.rendered_text || "";
  if (!text) {
    alert("Chưa có Nội dung chuẩn để copy. Hãy lưu lại trước.");
    return;
  }
  navigator.clipboard.writeText(text);
  const btn = document.getElementById('btnCopyJson');
  const og = btn.textContent;
  btn.textContent = '✓ Đã copy!';
  btn.style.borderColor = 'var(--success)';
  btn.style.color = 'var(--success)';
  setTimeout(() => { btn.textContent = og; btn.style.borderColor = ''; btn.style.color = ''; }, 2000);
}

// ═══ Approve / Reject ═══
async function approveDetail(newStatus) {
  if (!currentDetailCode) return;
  try {
    const res = await fetch(`${API}/approve`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ magento_ref_code: currentDetailCode, status: newStatus }),
    });
    const data = await res.json();
    if (data.status !== 'success') throw new Error(data.message);

    // Update buttons
    document.getElementById('btnApprove').style.display = newStatus === 1 ? 'none' : '';
    document.getElementById('btnReject').style.display = newStatus === 1 ? '' : 'none';

    // Flash feedback
    const label = newStatus === 1 ? '✅ Đã duyệt!' : '✕ Đã hủy duyệt';
    const body = document.getElementById('detailBody');
    if (body) {
        const toast = document.createElement('div');
        toast.style.cssText = 'padding:10px 14px;border-radius:8px;font-size:13px;font-weight:600;margin-bottom:12px;' +
          (newStatus === 1 ? 'background:var(--success-light);color:var(--success)' : 'background:#fff3cd;color:#856404');
        toast.textContent = label;
        body.prepend(toast);
        setTimeout(() => toast.remove(), 3000);
    }

    // Re-fetch latest description data from DB and refresh detail panel
    try {
      const savedRes = await fetch(`${API}/saved/${encodeURIComponent(currentDetailCode)}`);
      if (savedRes.ok) {
        const savedData = await savedRes.json();
        if (savedData.status === 'success' && savedData.data) {
          // Merge approval status into currentDetail and re-render Dàn trang
          currentDetail = { ...currentDetail, ...savedData.data, descStatus: newStatus };
          const tab = document.querySelector('.desc-tab-btn.active');
          if (tab) tab.click(); // Re-trigger active tab render
        }
      }
    } catch (_) { /* silently ignore refresh errors */ }

    // Refresh table stats
    loadOverview();
  } catch (e) {
    alert('Lỗi: ' + e.message);
  }
}


// ═══ Approve from Table Row ═══
async function approveRow(code, newStatus, btn) {
  const ogHtml = btn.innerHTML;
  btn.innerHTML = '<span class="spinner-sm"></span>';
  btn.disabled = true;
  try {
    const res = await fetch(`${API}/approve`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ internal_ref_code: code, status: newStatus }),
    });
    const data = await res.json();
    if (data.status !== 'success') throw new Error(data.message);

    // Update the button itself
    if (newStatus === 1) {
      btn.style.background = '#dc3545';
      btn.innerHTML = '✕ Hủy';
      btn.setAttribute('onclick', `event.stopPropagation();approveRow('${code}',0,this)`);
    } else {
      btn.style.background = '#28a745';
      btn.innerHTML = '✓ Duyệt';
      btn.setAttribute('onclick', `event.stopPropagation();approveRow('${code}',1,this)`);
    }

    // Update status badge in same row
    const row = btn.closest('tr');
    if (row) {
      const badge = row.querySelector('.status-badge');
      if (badge) {
        if (newStatus === 1) {
          badge.className = 'status-badge done';
          badge.textContent = '✅ Đã duyệt';
        } else {
          badge.className = 'status-badge pending';
          badge.textContent = '⏳ Chờ duyệt';
        }
      }
    }

    // Refresh stats
    loadOverview();
  } catch (e) {
    alert('Lỗi: ' + e.message);
    btn.innerHTML = ogHtml;
  } finally {
    btn.disabled = false;
  }
}

// ═══ Tabs & Fields ═══
let currentTab = 'products';

function switchTab(tab) {
  currentTab = tab;
  document.getElementById('tabProducts').className = tab === 'products' ? 'tab-btn active' : 'tab-btn';
  document.getElementById('tabProducts').style.borderBottomColor = tab === 'products' ? 'var(--primary)' : 'transparent';
  document.getElementById('tabProducts').style.color = tab === 'products' ? 'var(--primary)' : 'var(--muted-fg)';
  
  document.getElementById('tabFields').className = tab === 'fields' ? 'tab-btn active' : 'tab-btn';
  document.getElementById('tabFields').style.borderBottomColor = tab === 'fields' ? 'var(--primary)' : 'transparent';
  document.getElementById('tabFields').style.color = tab === 'fields' ? 'var(--primary)' : 'var(--muted-fg)';

  const tabCleanData = document.getElementById('tabCleanData');
  if (tabCleanData) {
    tabCleanData.className = tab === 'cleanData' ? 'tab-btn active' : 'tab-btn';
    tabCleanData.style.borderBottomColor = tab === 'cleanData' ? 'var(--primary)' : 'transparent';
    tabCleanData.style.color = tab === 'cleanData' ? 'var(--primary)' : 'var(--muted-fg)';
  }
  
  document.getElementById('sectionProducts').style.display = tab === 'products' ? 'block' : 'none';
  document.getElementById('sectionFields').style.display = tab === 'fields' ? 'block' : 'none';
  document.getElementById('sectionCleanData').style.display = tab === 'cleanData' ? 'block' : 'none';
  
  if (tab === 'fields') {
    loadFields();
  } else {
    loadProducts();
  }
}

async function loadFields() {
  const tbody = document.getElementById('fieldsTableBody');
  tbody.innerHTML = '<tr><td colspan="5" class="table-loading"><div class="spinner-sm"></div> Đang tải...</td></tr>';
  try {
    const res = await fetch(`${API}/fields`);
    const data = await res.json();
    if (data.status !== 'success') throw new Error(data.message);
    
    if (data.data.length === 0) {
      tbody.innerHTML = '<tr><td colspan="5" class="table-loading">Chưa có cấu hình trường nào.</td></tr>';
      return;
    }
    
    tbody.innerHTML = data.data.map((f, i) => `
      <tr style="opacity: ${f.is_active ? '1' : '0.5'}">
        <td style="font-family:var(--font-mono); font-size:12px; font-weight:600;">${esc(f.field_key)}</td>
        <td style="font-weight:600;">${esc(f.field_label)}</td>
        <td style="font-size:12px; color:var(--secondary-fg);">${esc(f.field_instruction)}</td>
        <td>
          <button class="btn btn-sm" style="background:${f.is_active ? '#28a745' : '#6c757d'}; color:#fff; border:none;" onclick="toggleField('${f.field_key}', ${!f.is_active})">${f.is_active ? 'Bật' : 'Tắt'}</button>
        </td>
        <td>
          <button class="btn btn-outline btn-sm" onclick="deleteField('${f.field_key}')" style="color:var(--warn); border-color:var(--warn);">Xóa</button>
        </td>
      </tr>
    `).join('');
  } catch (e) {
    tbody.innerHTML = `<tr><td colspan="5" class="table-loading" style="color:var(--warn)">Lỗi: ${esc(e.message)}</td></tr>`;
  }
}

async function toggleField(key, newStatus) {
  try {
    const res = await fetch(`${API}/fields/${key}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ is_active: newStatus }),
    });
    const data = await res.json();
    if (data.status !== 'success') throw new Error(data.message);
    loadFields();
  } catch (e) {
    alert('Lỗi: ' + e.message);
  }
}

async function deleteField(key) {
  if (!confirm(`Bạn có chắc chắn muốn xóa trường ${key}?`)) return;
  try {
    const res = await fetch(`${API}/fields/${key}`, { method: 'DELETE' });
    const data = await res.json();
    if (data.status !== 'success') throw new Error(data.message);
    loadFields();
  } catch (e) {
    alert('Lỗi: ' + e.message);
  }
}

async function showFieldForm() {
  const key = prompt('Nhập Key (viết liền không dấu, VD: chat_lieu_moi):');
  if (!key) return;
  const label = prompt('Nhập Label hiển thị:');
  if (!label) return;
  const instruction = prompt('Nhập Prompt (hướng dẫn AI sinh dữ liệu cho trường này):');
  
  try {
    const res = await fetch(`${API}/fields`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ field_key: key, field_label: label, field_instruction: instruction || '' }),
    });
    const data = await res.json();
    if (data.status !== 'success') throw new Error(data.message);
    loadFields();
  } catch (e) {
    alert('Lỗi: ' + e.message);
  }
}

// ═══ Utils ═══
function esc(str) {
  if (!str) return '';
  const d = document.createElement('div');
  d.textContent = String(str);
  return d.innerHTML;
}

// ═══ Edit Text in Popup ═══
async function savePopupText() {
  if (!currentDetailCode) return;

  // Detect active tab
  const isCleanTab = document.getElementById('detailBodyClean')?.style.display !== 'none';

  if (isCleanTab) {
    // ── Tab "Dàn trang (Chuẩn)" → collect field-val-* and call /update ──
    const btn = document.getElementById('btnSavePopupText');
    const oldText = btn.innerText;
    btn.innerText = 'Đang lưu...';
    btn.disabled = true;

    try {
      // Collect all editable field values from Dàn trang tab only
      const newData = {};
      // Collect from dantrang-val-* (editable spans in Dàn trang view)
      document.querySelectorAll('#detailBodyClean [id^="dantrang-val-"]').forEach(el => {
        const key = el.id.replace('dantrang-val-', '');
        newData[key] = el.innerText.trim();
      });
      // Fallback: also collect from hidden field-val-* in Fields tab (for fields not shown as editable)
      document.querySelectorAll('#detailBodyFields [id^="field-val-"]').forEach(el => {
        const key = el.id.replace('field-val-', '');
        if (!(key in newData)) newData[key] = el.innerText.trim();
      });

      if (Object.keys(newData).length === 0) {
        btn.innerText = '⚠️ Không có field';
        setTimeout(() => { btn.innerText = oldText; btn.disabled = false; }, 2000);
        return;
      }

      console.log('[SAVE] Sending description_data:', newData);

      const res = await fetch(`${API}/saved/${encodeURIComponent(currentDetailCode)}/update`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ description_data: newData })
      });
      const data = await res.json();
      if (data.status !== 'success') throw new Error(data.message);

      // Patch currentDetail memory
      if (window.currentDetailDataForCleanTab?.data) {
        Object.assign(window.currentDetailDataForCleanTab.data, newData);
      }

      btn.innerText = '✅ Đã lưu';
      setTimeout(() => { btn.innerText = oldText; btn.disabled = false; }, 2000);
    } catch (e) {
      alert('Lỗi lưu: ' + e.message);
      btn.innerText = oldText;
      btn.disabled = false;
    }
    return;
  }

  // ── Tab "Clean Descripts" → save text via /update-text ──
  const embedEditor = document.getElementById('detailPreEmbed');
  if (!embedEditor) return;

  const updatedText = embedEditor.innerText;
  const btn2 = document.getElementById('btnSavePopupText');
  const oldText2 = btn2.innerText;
  btn2.innerText = 'Đang lưu...';
  btn2.disabled = true;

  try {
    const res = await fetch(`${API}/saved/${encodeURIComponent(currentDetailCode)}/update-text`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ clean_description: updatedText })
    });
    const data = await res.json();
    if (data.status === 'success') {
      btn2.innerText = '✅ Đã lưu';
      setTimeout(() => { btn2.innerText = oldText2; btn2.disabled = false; }, 2000);
      if (window.currentDetailDataForCleanTab?.description) {
        window.currentDetailDataForCleanTab.description.rendered_text = updatedText;
        window.currentDetailDataForCleanTab.description.clean_description = updatedText;
      }
      if (window.currentDetailDataForCleanTab) {
        window.currentDetailDataForCleanTab.clean_description = updatedText;
      }
    } else {
      throw new Error(data.message || 'Lỗi không xác định');
    }
  } catch (e) {
    alert('Lỗi lưu text: ' + e.message);
    btn2.innerText = oldText2;
    btn2.disabled = false;
  }
}

function copyPopupText() {
  const editor = document.getElementById('detailPreEmbed');
  if (!editor) return;
  navigator.clipboard.writeText(editor.innerText).then(() => {
    const btn = document.getElementById('btnCopyJson');
    const oldText = btn.innerText;
    btn.innerText = '✅ Đã Copy';
    setTimeout(() => { btn.innerText = oldText; }, 2000);
  });
}
// ─── AI CODEX INLINE EDITOR ───
let selectedTextInfo = { text: '', context: '', range: null };

function setupInlineEdit() {
  const embedBody = document.getElementById('detailPreEmbed');
  const popup = document.getElementById('inlineEditPopup');

  embedBody.addEventListener('mouseup', function(e) {
    if (embedBody.contentEditable !== "true") return; // Only trigger if unlocked

    const selection = window.getSelection();
    const text = selection.toString().trim();
    
    if (text.length > 5) {
        // Find whole text context
        const context = embedBody.innerText;
        
        selectedTextInfo = {
            text: text,
            context: context,
            range: selection.getRangeAt(0).cloneRange()
        };
        
        // Position popup next to cursor
        popup.style.display = 'block';
        popup.style.top = (e.pageY + 10) + 'px';
        popup.style.left = e.pageX + 'px';
    } else {
        popup.style.display = 'none';
    }
  });

  document.addEventListener('mousedown', function(e) {
    if (!popup.contains(e.target) && !embedBody.contains(e.target)) {
        popup.style.display = 'none';
    }
  });
}

async function triggerInlineEdit(action) {
  const popup = document.getElementById('inlineEditPopup');
  popup.style.display = 'none';
  if (!selectedTextInfo.text || !selectedTextInfo.range) return;

  // Visual feedback injection
  const span = document.createElement('span');
  span.className = 'agent-editing';
  span.style.backgroundColor = '#fbbf24';
  span.style.color = 'black';
  span.textContent = `[⏳ AI Codex đang xử lý...]`;
  selectedTextInfo.range.deleteContents();
  selectedTextInfo.range.insertNode(span);

  try {
      let enrichedContext = "";
      if (action === 'enrich') {
         enrichedContext = "Đây là thông tin của một sản phẩm thời trang. Hãy bổ sung gợi ý cực hay về dịp mặc thích hợp, những ngày lễ hội có thể diện sản phẩm, hoặc cách ứng dụng thực tế vào đời sống. Giữ giọng văn xuất sắc của Stylist chuyên gia thời trang, nhưng KHÔNG viết dài dòng lê thê.\n\n" + selectedTextInfo.context;
      } else {
         enrichedContext = "Đây là thông tin của một sản phẩm thời trang. Hãy thực hiện yêu cầu chỉnh sửa trên đoạn text được đánh dấu.\n\n" + selectedTextInfo.context;
      }

      // Reuse the existing ai-report capability
      const res = await fetch('/api/report-inline-edit', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
              selected_text: selectedTextInfo.text,
              action: action,
              context: enrichedContext
          })
      });
      const data = await res.json();
      
      span.style.backgroundColor = '#d1fae5'; // success green
      span.innerHTML = `${data.new_text} <em style="font-size:10px;color:#059669;cursor:pointer;padding-left:4px" title="Chấp nhận gợi ý này">[Chấp nhận]</em>`;
      
      const acceptBtn = span.querySelector('em');
      acceptBtn.onclick = function() {
          span.outerHTML = data.new_text;
      };
  } catch(e) {
      span.style.backgroundColor = '#fecaca';
      span.textContent = selectedTextInfo.text; // Revert safely
      alert('Lỗi gọi AI Codex: ' + e.message);
  }
}

// Initialize on load
setupInlineEdit();

// ═══ SIZE GUIDE ENRICHMENT ═══
async function generateSingleSize(code, name, btn) {
  const ogText = btn.textContent;
  btn.innerHTML = '<span class="spinner-sm"></span>';
  btn.disabled = true;

  try {
    const res = await fetch('/api/bulk/enrich-size-single', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ internal_ref_code: code }),
    });
    const data = await res.json();
    if (data.status === 'error') throw new Error(data.message);

    alert(`✅ Đã sinh Size Guide cho ${data.name || code}!\n\nSize: ${JSON.stringify(data.size_scale)}\n\nClick vào sản phẩm để xem chi tiết.`);
    
    // Refresh the detail if it's open
    if (currentDetailCode === code) {
      openDetail(code, name);
    }
  } catch (e) {
    alert('❌ Lỗi: ' + e.message);
  } finally {
    btn.textContent = ogText;
    btn.disabled = false;
  }
}

async function batchEnrichSize() {
  // First get stats
  try {
    const statsRes = await fetch('/api/bulk/size-stats');
    const stats = await statsRes.json();
    if (stats.status !== 'success') throw new Error(stats.message);

    if (stats.needs_enrichment <= 0) {
      alert('🎉 Tất cả sản phẩm đã có hướng dẫn size!');
      return;
    }

    if (!confirm(`📏 Phát hiện ${stats.needs_enrichment} sản phẩm cần bơm Size Guide AI.\n\n` +
      `Tổng matched: ${stats.matched_products}\n` +
      `Đã có size guide: ${stats.has_size_guide}\n` +
      `Cần bơm: ${stats.needs_enrichment}\n\n` +
      `Bấm OK để chạy batch AI (ngầm)?`)) return;

    const btn = document.getElementById('btnBatchSize');
    const ogText = btn.innerHTML;
    btn.innerHTML = '<div class="spinner-sm"></div> Đang gửi...';
    btn.disabled = true;

    const res = await fetch('/api/bulk/enrich-size-batch', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ codes: [] }) // Empty = all needing enrichment
    });
    const data = await res.json();
    if (data.status === 'error') throw new Error(data.message);

    alert(`✅ ${data.message}`);
    btn.innerHTML = ogText;
    btn.disabled = false;

  } catch (e) {
    alert('❌ Lỗi: ' + e.message);
    const btn = document.getElementById('btnBatchSize');
    if (btn) { btn.innerHTML = '📏 Bơm Size Guide'; btn.disabled = false; }
  }
}
