<?php
// public/reports.php
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/auth_stub.php';

session_start();

// Filter selectlar uchun ro'yxatlar
$products   = $pdo->query("SELECT id, name FROM products   WHERE is_active = 1 ORDER BY name")->fetchAll();
$users      = $pdo->query("SELECT id, name FROM users      WHERE is_active = 1 ORDER BY name")->fetchAll();
$categories = $pdo->query("SELECT id, name FROM categories WHERE is_active = 1 ORDER BY name")->fetchAll();
?>
<!DOCTYPE html>
<html lang="uz">
<head>
  <meta charset="UTF-8">
  <title>Hisobot – Markirovka bloklari</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <!-- Bootstrap 5 -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
  <!-- FontAwesome -->
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" rel="stylesheet">
  <!-- Toastr -->
  <link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" rel="stylesheet">

  <style>
    :root {
      --brand-main: #0d47a1;
      --brand-soft: #e5edff;
      --brand-accent: #22c55e;
      --bg-soft: #f3f4f8;
      --card-bg: rgba(255,255,255,0.96);
      --border-soft: #d1d9e6;
      --text-main: #0b1220;
      --text-muted: #6b7280;
    }

    body {
      min-height: 100vh;
      margin: 0;
      background: radial-gradient(circle at top left, #c7d2fe 0, transparent 45%),
                  radial-gradient(circle at bottom right, #bfdbfe 0, transparent 45%),
                  #eef2ff;
      color: var(--text-main);
    }

    .page-wrapper {
      max-width: 1200px;
      margin: 0 auto;
    }

    .navbar {
      background: rgba(13,71,161,0.96);
      backdrop-filter: blur(10px);
      box-shadow: 0 10px 25px rgba(15,23,42,0.35);
    }
    .navbar-brand, .navbar-nav .nav-link, .navbar-text {
      color: #fff !important;
    }
    .navbar-nav .nav-link {
      font-size: 0.92rem;
      opacity: 0.9;
    }
    .navbar-nav .nav-link.active {
      opacity: 1;
      font-weight: 600;
      border-bottom: 2px solid #fff;
    }

    .card {
      border-radius: 18px;
      box-shadow: 0 16px 40px rgba(15,23,42,0.08);
      border: 1px solid rgba(148,163,184,0.35);
      background: var(--card-bg);
    }

    .form-label {
      font-weight: 600;
      color: var(--text-main);
    }

    .pill-heading {
      font-size: 0.8rem;
      text-transform: uppercase;
      letter-spacing: 0.1em;
      color: var(--text-muted);
    }

    .badge-status {
      font-size: 0.75rem;
      border-radius: 999px;
      padding: 0.2rem 0.55rem;
    }

    .table thead {
      background: #eff3ff;
      font-size: 0.88rem;
    }

    .table tbody tr {
      font-size: 0.86rem;
      transition: background 0.12s ease;
      position: relative; /* overlay uchun */
    }
    .table tbody tr:hover {
      background: #f9fafb;
    }

    .search-input {
      max-width: 260px;
    }

    .filter-pill {
      background: #f1f5f9;
      border-radius: 999px;
      padding: 0.25rem 0.75rem;
      font-size: 0.78rem;
      color: #64748b;
    }

    /* ✅ Rasm preview kesilmasin (tepasi/pasti ko‘rinsin) */
    .thumb-img {
      width: 82px;
      height: 82px;
      object-fit: contain;
      border-radius: 10px;
      border: 1px solid #e5e7eb;
      background: #fff;
      padding: 7px;
      box-shadow: 0 10px 22px rgba(15,23,42,0.10);
    }

    .details-img {
      width: 290px;
      height: 290px;
      object-fit: contain;
      border-radius: 16px;
      border: 1px solid #e5e7eb;
      background: #fff;
      padding: 12px;
      box-shadow: 0 18px 36px rgba(15,23,42,0.12);
    }

    /* Kodlar jadvali (modal ichida) uchun ranglar */
    .code-row-sold {
      background-color: #ecfdf5 !important;
      border-left: 3px solid #16a34a;
    }
    .code-row-issue {
      background-color: #fef2f2 !important;
      border-left: 3px solid #dc2626;
    }
    .code-sale-badge {
      font-size: 0.75rem;
      border-radius: 999px;
      padding: 0.1rem 0.55rem;
    }

    /* GTIN / SSCC ustuni ichida statuslar */
    .gtin-cell-maincode {
      display: block;
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
      font-size: 0.83rem;
    }
    .gtin-cell-status {
      margin-top: 0.25rem;
      display: flex;
      flex-wrap: wrap;
      gap: 0.25rem;
      align-items: center;
    }

    /* ✅ “Sotilgan: 8/8” – fon yo‘q, faqat matn + soya */
    .sale-lite {
      display: inline-flex;
      align-items: center;
      gap: 0.35rem;
      font-weight: 900;
      font-size: 0.70rem;
      letter-spacing: 0.06em;
      text-transform: uppercase;
      color: #16a34a;
      text-shadow: 0 16px 28px rgba(15,23,42,0.40);
      user-select: none;
      white-space: nowrap;
    }

    /* Xtrace pilllar (o‘z holicha) */
    .status-pill {
      display: inline-flex;
      align-items: center;
      gap: 0.25rem;
      font-size: 0.7rem;
      border-radius: 999px;
      padding: 0.15rem 0.55rem;
      text-transform: uppercase;
      letter-spacing: 0.04em;
      font-weight: 600;
    }

    /* ✅ WATERMARK overlay (Guruh kod → Amal) */
    .row-overlay {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      height: 60px;
      display: flex;
      align-items: center;
      justify-content: center;
      pointer-events: none;
      z-index: 1;          /* td kontentdan past */
      overflow: hidden;
      opacity: 0.14;       /* yengil bo‘lsin */
      filter: saturate(120%);
    }

    .row-overlay .row-overlay-text {
      width: 100%;
      text-align: center;
      font-weight: 900;
      font-size: 0.95rem;
      transform: rotate(-1deg);
      transform-origin: center;
      white-space: nowrap;
      letter-spacing: 0.14em;
      text-shadow: 0 20px 34px rgba(15,23,42,0.62);
      user-select: none;
    }

    /* Rang faqat matnda */
    .row-overlay.sold .row-overlay-text { color: #16a34a; }
    .row-overlay.error .row-overlay-text { color: #dc2626; }
    .row-overlay.warning .row-overlay-text { color: #b45309; }
    .row-overlay.sold_error .row-overlay-text { color: #f97316; }
    .row-overlay.sold_warning .row-overlay-text { color: #d97706; }

    /* ✅ overlay kontentga halal bermasin (td kontent ustida tursin) */
    #blocks-table tbody td {
      position: relative;
      z-index: 2;
      background: transparent;
    }

    /* ✅ GLOBAL LOADING OVERLAY */
    #globalLoading{
      position: fixed;
      inset: 0;
      background: rgba(255,255,255,0.68);
      backdrop-filter: blur(6px);
      z-index: 99999;
      display:flex;
      align-items:center;
      justify-content:center;
      padding: 16px;
    }
    #globalLoading .gl-box{
      background: rgba(255,255,255,0.92);
      border: 1px solid rgba(148,163,184,0.35);
      box-shadow: 0 24px 60px rgba(15,23,42,0.20);
      border-radius: 18px;
      padding: 16px 18px;
      display:flex;
      align-items:center;
      gap: 14px;
      min-width: 300px;
      max-width: 92vw;
    }
    #globalLoading .spinner-border{
      width: 2.2rem;
      height: 2.2rem;
    }
    #globalLoading .gl-title{
      font-weight: 900;
      color: #0b1220;
      line-height: 1.1;
    }
    #globalLoading .gl-sub{
      font-size: 0.90rem;
      color: #6b7280;
      margin-top: 3px;
    }

    @media (max-width: 767.98px) {
      .page-wrapper { padding-inline: 0.4rem; }
      .search-input { max-width: 100%; }
      .details-img { width: 240px; height: 240px; }
    }
  </style>
</head>
<body>

<?php
  $active = 'reports';
  require __DIR__ . '/navbar.php';
?>

<div class="page-wrapper">
  <div class="py-4">

    <div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center mb-3">
      <div>
        <h3 class="mb-1">Bloklar hisobot</h3>
        <div class="text-muted">
          Har bir blok bo‘yicha GTIN2 / SSCC18, foydalanuvchi, mahsulot va vaqt kesimida.
        </div>
      </div>
    </div>

    <!-- FILTER CARD -->
    <div class="card mb-3">
      <div class="card-body">
        <div class="pill-heading mb-3">Filter va qidiruv</div>
        <div class="row g-3">
          <div class="col-md-3">
            <label class="form-label" for="filter_product">Mahsulot</label>
            <select id="filter_product" class="form-select">
              <option value="0">Barchasi</option>
              <?php foreach ($products as $p): ?>
                <option value="<?= (int)$p['id'] ?>"><?= htmlspecialchars($p['name']) ?></option>
              <?php endforeach; ?>
            </select>
          </div>

          <div class="col-md-3">
            <label class="form-label" for="filter_category">Kategoriya</label>
            <select id="filter_category" class="form-select">
              <option value="0">Barchasi</option>
              <?php foreach ($categories as $c): ?>
                <option value="<?= (int)$c['id'] ?>"><?= htmlspecialchars($c['name']) ?></option>
              <?php endforeach; ?>
            </select>
          </div>

          <div class="col-md-3">
            <label class="form-label" for="filter_user">Foydalanuvchi</label>
            <select id="filter_user" class="form-select">
              <option value="0">Barchasi</option>
              <?php foreach ($users as $u): ?>
                <option value="<?= (int)$u['id'] ?>"><?= htmlspecialchars($u['name']) ?></option>
              <?php endforeach; ?>
            </select>
          </div>

          <div class="col-md-3">
            <label class="form-label" for="filter_mode">Turi (manual/auto)</label>
            <select id="filter_mode" class="form-select">
              <option value="">Barchasi</option>
              <option value="manual">Manual</option>
              <option value="auto">Auto</option>
            </select>
          </div>

          <div class="col-md-3">
            <label class="form-label" for="filter_date_from">Sana (dan)</label>
            <input type="date" id="filter_date_from" class="form-control">
          </div>
          <div class="col-md-3">
            <label class="form-label" for="filter_date_to">Sana (gacha)</label>
            <input type="date" id="filter_date_to" class="form-control">
          </div>

          <div class="col-md-3">
            <label class="form-label" for="filter_search">Qidirish</label>
            <input type="text" id="filter_search" class="form-control search-input"
                   placeholder="GTIN2 / mahsulot / ID">
          </div>

          <div class="col-md-3">
            <label class="form-label" for="filter_status">Status (Xtrace / Sotuv)</label>
            <select id="filter_status" class="form-select">
              <option value="">Barchasi</option>
              <option value="sold">Faqat sotilgan bloklar (to‘liq)</option>
              <option value="error">Xtrace xatoliklari</option>
              <option value="sold_error">Sotilgan (to‘liq) va Xtrace xatolik</option>
            </select>
          </div>

          <div class="col-md-3">
            <label class="form-label" for="per_page">Sahifadagi satrlar</label>
            <select id="per_page" class="form-select">
              <option value="10">10</option>
              <option value="20" selected>20</option>
              <option value="50">50</option>
              <option value="100">100</option>
            </select>
          </div>

          <div class="col-12 d-flex justify-content-between flex-wrap gap-2 mt-2">
            <button type="button" class="btn btn-primary" id="btn-apply-filters">
              <i class="fa-solid fa-filter"></i> Filterni qo‘llash
            </button>
            <div class="d-flex flex-wrap gap-2" id="export-buttons">
              <button type="button" class="btn btn-outline-secondary btn-sm" data-format="csv">
                <i class="fa-solid fa-file-csv"></i> CSV
              </button>
              <button type="button" class="btn btn-outline-secondary btn-sm" data-format="xls">
                <i class="fa-solid fa-file-excel"></i> XLS
              </button>
              <button type="button" class="btn btn-outline-secondary btn-sm" data-format="xlsx">
                <i class="fa-solid fa-file-excel"></i> XLSX
              </button>
              <button type="button" class="btn btn-outline-secondary btn-sm" data-format="doc">
                <i class="fa-solid fa-file-word"></i> DOC
              </button>
              <button type="button" class="btn btn-outline-secondary btn-sm" data-format="pdf">
                <i class="fa-solid fa-file-pdf"></i> PDF
              </button>
              <button type="button" class="btn btn-outline-secondary btn-sm" data-format="png">
                <i class="fa-solid fa-image"></i> PNG
              </button>
              <button type="button" class="btn btn-outline-secondary btn-sm" data-format="jpg">
                <i class="fa-regular fa-image"></i> JPG
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- TABLE CARD -->
    <div class="card">
      <div class="card-body">
        <div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center mb-2 gap-2">
          <div>
            <div class="pill-heading mb-1">Ro‘yxat</div>
            <h5 class="mb-0">Bloklar</h5>
          </div>
          <div id="pagination-info" class="filter-pill">
            Sahifa 1/1, jami 0 blok
          </div>
        </div>

        <div id="blocks-table-wrapper">
          <table class="table table-hover align-middle" id="blocks-table">
            <thead>
            <tr>
              <th>ID</th>
              <th>Rasm</th>
              <th>Mahsulot</th>
              <th>Guruh kod (GTIN2 / SSCC18)</th>
              <th>Mode</th>
              <th>From ID</th>
              <th>Until ID</th>
              <th>Foydalanuvchi</th>
              <th>Report ID</th>
              <th>Yaratilgan</th>
              <th>Amal</th>
            </tr>
            </thead>
            <tbody>
              <tr><td colspan="11" class="text-center py-3 text-muted">Ma'lumotlar yuklanmoqda...</td></tr>
            </tbody>
          </table>
        </div>

        <div class="d-flex justify-content-between align-items-center mt-2 flex-wrap gap-2">
          <div>
            <button type="button" class="btn btn-outline-secondary btn-sm" id="btn-prev">
              <i class="fa-solid fa-chevron-left"></i> Oldingi
            </button>
            <button type="button" class="btn btn-outline-secondary btn-sm" id="btn-next">
              Keyingi <i class="fa-solid fa-chevron-right"></i>
            </button>
          </div>
          <div class="text-muted small" id="current-filters-label"></div>
        </div>
      </div>
    </div>

  </div>
</div>

<!-- BATAFSIL MODAL -->
<div class="modal fade" id="blockDetailsModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-scrollable">
    <div class="modal-content" id="blockDetailsContent">
      <div class="modal-header">
        <h5 class="modal-title">
          <i class="fa-solid fa-circle-info me-1"></i> Blok haqida batafsil
          <span class="badge bg-secondary ms-2" id="details_block_id"></span>
        </h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>
      <div class="modal-body">
        <div class="row g-3">
          <div class="col-md-4 text-center">
            <img id="details_image" src="" alt="Mahsulot rasmi" class="details-img mb-2" style="display:none;">
            <div class="small text-muted" id="details_category_name"></div>
          </div>
          <div class="col-md-8">
            <h5 id="details_product_name" class="mb-2"></h5>
            <dl class="row mb-2">
              <dt class="col-sm-4">Guruh / transport kodi</dt>
              <dd class="col-sm-8"><code id="details_code"></code></dd>

              <dt class="col-sm-4">Mode</dt>
              <dd class="col-sm-8" id="details_mode"></dd>

              <dt class="col-sm-4">Foydalanuvchi</dt>
              <dd class="col-sm-8" id="details_user"></dd>

              <dt class="col-sm-4">Report ID</dt>
              <dd class="col-sm-8" id="details_report_id"></dd>

              <dt class="col-sm-4">Yaratilgan</dt>
              <dd class="col-sm-8" id="details_created"></dd>
            </dl>

            <div id="details_xtrace_status_box" class="mb-2"></div>
            <div id="details_integrity_box" class="mb-2"></div>

            <div class="accordion" id="codesAccordion">
              <div class="accordion-item">
                <h2 class="accordion-header" id="headingCodes">
                  <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
                          data-bs-target="#collapseCodes" aria-expanded="false" aria-controls="collapseCodes">
                    Guruh ichidagi kodlar ro‘yxati
                  </button>
                </h2>
                <div id="collapseCodes" class="accordion-collapse collapse" aria-labelledby="headingCodes"
                     data-bs-parent="#codesAccordion">
                  <div class="accordion-body" id="details_codes_container">
                    <div class="text-muted small">Yuklanmoqda...</div>
                  </div>
                </div>
              </div>
            </div>

          </div>
        </div>
      </div>
      <div class="modal-footer">
        <div class="me-auto d-flex flex-wrap gap-2">
          <button type="button" class="btn btn-outline-secondary btn-sm" onclick="exportBlockDetails('csv')">CSV</button>
          <button type="button" class="btn btn-outline-secondary btn-sm" onclick="exportBlockDetails('xls')">XLS</button>
          <button type="button" class="btn btn-outline-secondary btn-sm" onclick="exportBlockDetails('xlsx')">XLSX</button>
          <button type="button" class="btn btn-outline-secondary btn-sm" onclick="exportBlockDetails('doc')">DOC</button>
          <button type="button" class="btn btn-outline-secondary btn-sm" onclick="exportBlockDetails('pdf')">PDF</button>
          <button type="button" class="btn btn-outline-secondary btn-sm" onclick="exportBlockDetails('png')">PNG</button>
          <button type="button" class="btn btn-outline-secondary btn-sm" onclick="exportBlockDetails('jpg')">JPG</button>
        </div>
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Yopish</button>
      </div>
    </div>
  </div>
</div>

<!-- ✅ GLOBAL LOADING OVERLAY -->
<div id="globalLoading" style="display:none;">
  <div class="gl-box">
    <div class="spinner-border" role="status" aria-hidden="true"></div>
    <div class="gl-text">
      <div class="gl-title" id="glTitle">Yuklanmoqda...</div>
      <div class="gl-sub" id="glSub">Iltimos kuting</div>
    </div>
  </div>
</div>

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>

<script>
  const apiUrl = 'api/blocks.php';
  const BASE_PATH = '/mark2/';

  let currentPage   = 1;
  let pageCount     = 1;
  let totalRows     = 0;
  let perPage       = 20;
  let lastResponse  = [];
  let currentBlockDetails = null;

  // ✅ loader counter
  let __loadingCount = 0;

  toastr.options = {
    positionClass: "toast-top-right",
    timeOut: 3000
  };

  function showGlobalLoading(title, sub){
    __loadingCount++;
    $('#glTitle').text(title || 'Yuklanmoqda...');
    $('#glSub').text(sub || 'Iltimos kuting');
    $('#globalLoading').show();
  }

  function hideGlobalLoading(){
    __loadingCount = Math.max(0, __loadingCount - 1);
    if (__loadingCount === 0) $('#globalLoading').hide();
  }

  function asPromise(jqXHR){
    return new Promise((resolve, reject) => {
      jqXHR.done(resolve).fail(reject);
    });
  }

  function withBase(path) {
    if (!path) return '';
    if (/^(https?:)?\/\//.test(path) || path.startsWith(BASE_PATH) || path.startsWith('data:')) {
      return path;
    }
    if (path[0] === '/') path = path.slice(1);
    return BASE_PATH + path;
  }

  $(function () {
    $('#btn-apply-filters').on('click', function () {
      currentPage = 1;
      loadBlocks();
    });

    $('#btn-prev').on('click', function () {
      if (currentPage > 1) {
        currentPage--;
        loadBlocks();
      }
    });

    $('#btn-next').on('click', function () {
      if (currentPage < pageCount) {
        currentPage++;
        loadBlocks();
      }
    });

    $('#per_page').on('change', function () {
      currentPage = 1;
      loadBlocks();
    });

    $('#filter_search').on('keypress', function (e) {
      if (e.which === 13) {
        currentPage = 1;
        loadBlocks();
      }
    });

    $('#export-buttons').on('click', 'button[data-format]', function () {
      const fmt = $(this).data('format');
      exportBlocks(fmt);
    });

    $('#filter_status').on('change', function () {
      applyStatusFilter();
    });

    loadBlocks();
  });

  function getFilterParams() {
    return {
      product_id:  $('#filter_product').val()  || 0,
      category_id: $('#filter_category').val() || 0,
      user_id:     $('#filter_user').val()     || 0,
      mode_type:   $('#filter_mode').val()     || '',
      date_from:   $('#filter_date_from').val()|| '',
      date_to:     $('#filter_date_to').val()  || '',
      search:      $('#filter_search').val()   || '',
      status_filter: $('#filter_status').val() || ''
    };
  }

  // ✅ 100%: list + check_reports tugamaguncha loader ketmaydi
  async function loadBlocks() {
    perPage = parseInt($('#per_page').val(), 10) || 20;
    const filters = getFilterParams();

    const params = {
      action:      'list',
      page:        currentPage,
      per_page:    perPage,
      product_id:  filters.product_id,
      category_id: filters.category_id,
      user_id:     filters.user_id,
      mode_type:   filters.mode_type,
      date_from:   filters.date_from,
      date_to:     filters.date_to,
      search:      filters.search
    };

    showGlobalLoading("Hisobot yuklanmoqda...", "Bloklar va statuslar tekshirilmoqda");

    $('#blocks-table tbody').html(
      '<tr><td colspan="11" class="text-center py-3 text-muted">Yuklanmoqda...</td></tr>'
    );

    try {
      const res = await asPromise($.getJSON(apiUrl, params));

      if (res.status !== 'ok') {
        toastr.error(res.message || 'Xatolik');
        return;
      }

      lastResponse = res.blocks || [];
      const pg = res.pagination || {};
      totalRows   = pg.total      || 0;
      currentPage = pg.page       || 1;
      pageCount   = pg.page_count || 1;

      renderTable(lastResponse);
      renderPaginationInfo();
      renderCurrentFiltersLabel();

      // ✅ check_reports ham kutiladi
      await refreshReportStatusesAwaitable();

    } catch (e) {
      toastr.error('Hisobotni yuklashda xatolik');
    } finally {
      hideGlobalLoading();
    }
  }

  function renderTable(rows) {
    const tbody = $('#blocks-table tbody');

    if (!rows.length) {
      tbody.html('<tr><td colspan="11" class="text-center py-3 text-muted">Bloklar topilmadi</td></tr>');
      return;
    }

    let html = '';
    rows.forEach(b => {
      const modeBadge = b.mode_type === 'auto'
        ? '<span class="badge bg-success-subtle text-success badge-status"><i class="fa-solid fa-robot"></i> auto</span>'
        : '<span class="badge bg-primary-subtle text-primary badge-status"><i class="fa-solid fa-hand"></i> manual</span>';

      const productBlock = `
        <div><strong>${escapeHtml(b.product_name || '')}</strong></div>
        <div class="small text-muted">${escapeHtml(b.category_name || '')}</div>
      `;

      const imgSrc = b.product_image ? withBase(b.product_image) : '';
      const imgHtml = imgSrc
        ? `<img src="${escapeHtml(imgSrc)}" alt="" class="thumb-img">`
        : '';

      const totalCodes = Number(b.total_codes || 0);
      const soldCodes  = Number(b.sold_codes || 0);

      // ✅ faqat FULL sold bo‘lsa (masalan 8/8) ko‘rsatamiz
      const isFullSold = (totalCodes > 0 && soldCodes === totalCodes);

      let saleBadge = '';
      if (isFullSold) {
        saleBadge = `
          <span class="sale-lite">
            <i class="fa-solid fa-check"></i>
            Sotilgan: ${soldCodes}/${totalCodes}
          </span>`;
      }

      html += `
        <tr data-id="${b.id}"
            data-total-codes="${totalCodes}"
            data-sold-codes="${soldCodes}"
            data-is-fullsold="${isFullSold ? 1 : 0}"
            data-overlay-text=""
            data-overlay-kind="">
          <td>${b.id}</td>
          <td>${imgHtml}</td>
          <td>${productBlock}</td>

          <!-- ✅ overlay boshlanadigan ustun -->
          <td class="col-code">
            <span class="gtin-cell-maincode"><code>${escapeHtml(b.gtin2_number || '')}</code></span>
            <div class="gtin-cell-status" data-status-badges-for="${b.id}">
              ${saleBadge}
            </div>
          </td>

          <td>${modeBadge}</td>
          <td>${escapeHtml(String(b.from_id || ''))}</td>
          <td>${escapeHtml(String(b.until_id || ''))}</td>
          <td>${escapeHtml(b.user_name || '')}</td>
          <td>${b.report_id !== null ? escapeHtml(b.report_id) : ''}</td>
          <td class="small text-muted">${escapeHtml(b.created_at || '')}</td>

          <!-- ✅ overlay tugaydigan ustun -->
          <td class="col-action">
            <div class="btn-group btn-group-sm" role="group">
              <button type="button" class="btn btn-outline-info" onclick="openDetails(${b.id})">
                <i class="fa-solid fa-circle-info"></i> Ko‘rish
              </button>
              <button type="button" class="btn btn-outline-danger" onclick="deleteBlock(${b.id})">
                <i class="fa-solid fa-trash-can"></i> O'chirish
              </button>
            </div>
          </td>
        </tr>
      `;
    });

    tbody.html(html);

    // ✅ Xtrace kelmasa ham FULL sold watermark ko‘rinsin
    $('#blocks-table tbody tr').each(function(){
      const row = $(this);
      const id = row.attr('data-id');
      const isFullSold = row.attr('data-is-fullsold') === '1';
      const totalCodes = Number(row.attr('data-total-codes') || 0);
      const soldCodes  = Number(row.attr('data-sold-codes') || 0);

      if (isFullSold) {
        const text = `Sotilgan: ${soldCodes}/${totalCodes}`;
        row.attr('data-overlay-text', text);
        row.attr('data-overlay-kind', 'sold');
        applyRowOverlayFromCodeToAction(id, text, 'sold');
      }
    });
  }

  function renderPaginationInfo() {
    $('#pagination-info').text(
      `Sahifa ${currentPage}/${pageCount}, jami ${totalRows} blok`
    );

    $('#btn-prev').prop('disabled', currentPage <= 1);
    $('#btn-next').prop('disabled', currentPage >= pageCount);
  }

  function renderCurrentFiltersLabel() {
    const f = getFilterParams();
    const parts = [];

    if (f.product_id && f.product_id !== '0')   parts.push('Mahsulot filtrlangan');
    if (f.category_id && f.category_id !== '0') parts.push('Kategoriya filtrlangan');
    if (f.user_id && f.user_id !== '0')         parts.push('Foydalanuvchi filtrlangan');
    if (f.mode_type)                            parts.push('Mode: ' + f.mode_type);
    if (f.date_from || f.date_to) {
      parts.push(`Sana: ${f.date_from || '...'} → ${f.date_to || '...'}`);
    }
    if (f.search)                               parts.push(`Qidiruv: "${f.search}"`);
    if (f.status_filter)                        parts.push('Status filtr: ' + f.status_filter);

    $('#current-filters-label').text(
      parts.length ? parts.join(' | ') : 'Filter qo‘llanmagan'
    );
  }

  function deleteBlock(id) {
    if (!confirm('Ushbu blokni o‘chirasizmi?')) return;

    showGlobalLoading("O‘chirilmoqda...", "Iltimos kuting");
    $.post(apiUrl, {action: 'delete', id: id}, function (res) {
      if (res.status !== 'ok') {
        toastr.error(res.message || 'Xatolik');
        hideGlobalLoading();
        return;
      }
      toastr.success('Blok o‘chirildi');
      hideGlobalLoading();
      loadBlocks();
    }, 'json').fail(function () {
      hideGlobalLoading();
      toastr.error('Server xatosi');
    });
  }

  // --- Umumiy hisobot eksporti ---
  function exportBlocks(format) {
    const filters = getFilterParams();

    if (format === 'pdf' || format === 'png' || format === 'jpg') {
      exportTableAsImageOrPdf(format);
      return;
    }

    showGlobalLoading("Export...", "Ma'lumotlar tayyorlanmoqda");

    const params = {
      action:      'list',
      page:        1,
      per_page:    100000,
      product_id:  filters.product_id,
      category_id: filters.category_id,
      user_id:     filters.user_id,
      mode_type:   filters.mode_type,
      date_from:   filters.date_from,
      date_to:     filters.date_to,
      search:      filters.search
    };

    $.getJSON(apiUrl, params)
      .done(function (res) {
        if (res.status !== 'ok') {
          toastr.error(res.message || 'Exportda xatolik');
          return;
        }
        const rows = res.blocks || [];
        if (!rows.length) {
          toastr.info('Export uchun ma\'lumot topilmadi');
          return;
        }
        const csv = buildCsv(rows);
        const now = new Date();
        const y = now.getFullYear();
        const m = String(now.getMonth() + 1).padStart(2, '0');
        const d = String(now.getDate()).padStart(2, '0');

        const extMap = {csv:'csv', xls:'xls', xlsx:'xlsx', doc:'doc'};
        const ext = extMap[format] || 'csv';
        const filename = `blocks_report_${y}${m}${d}.${ext}`;

        downloadTextFile(csv, filename);
      })
      .fail(function () {
        toastr.error('Exportda server xatosi');
      })
      .always(function(){
        hideGlobalLoading();
      });
  }

  function buildCsv(rows) {
    const header = [
      'ID',
      'Mahsulot',
      'Kategoriya',
      'GTIN2/SSCC18',
      'Mode',
      'FromID',
      'UntilID',
      'Foydalanuvchi',
      'ReportID',
      'TotalCodes',
      'SoldCodes',
      'CreatedAt'
    ];
    const lines = [];
    lines.push(header.join(';'));

    rows.forEach(b => {
      const line = [
        b.id,
        (b.product_name  || '').replace(/;/g, ','),
        (b.category_name || '').replace(/;/g, ','),
        (b.gtin2_number  || '').replace(/;/g, ','),
        b.mode_type,
        b.from_id,
        b.until_id,
        (b.user_name || '').replace(/;/g, ','),
        b.report_id !== null ? b.report_id : '',
        b.total_codes || 0,
        b.sold_codes || 0,
        b.created_at || ''
      ];
      lines.push(line.join(';'));
    });

    return lines.join('\r\n');
  }

  function downloadTextFile(content, filename) {
    const blob = new Blob([content], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }

  function exportTableAsImageOrPdf(format) {
    const el = document.getElementById('blocks-table-wrapper');
    if (!el) return;

    showGlobalLoading("Export...", "Rasm/PDF tayyorlanmoqda");

    html2canvas(el).then(canvas => {
      if (format === 'pdf') {
        const { jsPDF } = window.jspdf;
        const imgData = canvas.toDataURL('image/png');
        const pdf = new jsPDF('l', 'pt', [canvas.width, canvas.height]);
        pdf.addImage(imgData, 'PNG', 0, 0, canvas.width, canvas.height);
        pdf.save('blocks_table.pdf');
      } else {
        const mime = format === 'jpg' ? 'image/jpeg' : 'image/png';
        canvas.toBlob(function (blob) {
          const url = URL.createObjectURL(blob);
          const a = document.createElement('a');
          a.href = url;
          a.download = 'blocks_table.' + (format === 'jpg' ? 'jpg' : 'png');
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          URL.revokeObjectURL(url);
        }, mime);
      }
    }).finally(() => {
      hideGlobalLoading();
    });
  }

  // ✅ “S   O   T   I...” format + uzun takrorlash
  function spacedChars(str) {
    const s = String(str || '').toUpperCase();
    return s.split('').join('   ');
  }

  function buildLongOverlayText(text) {
    const base = spacedChars(text);
    let longText = base;
    while (longText.length < 520) {
      longText += '       ' + base;
    }
    return longText;
  }

  // ✅ overlay: Guruh kod ustunidan → Amal ustunigacha
  function applyRowOverlayFromCodeToAction(blockId, text, kind) {
    const row = document.querySelector('#blocks-table tbody tr[data-id="' + blockId + '"]');
    if (!row) return;

    // old overlay remove
    const old = row.querySelector('.row-overlay');
    if (old) old.remove();

    if (!text) return;

    const codeCell   = row.querySelector('td.col-code');
    const actionCell = row.querySelector('td.col-action');
    if (!codeCell || !actionCell) return;

    requestAnimationFrame(() => {
      const rowRect    = row.getBoundingClientRect();
      const codeRect   = codeCell.getBoundingClientRect();
      const actionRect = actionCell.getBoundingClientRect();

      const left  = (codeRect.left - rowRect.left);
      const width = (actionRect.right - codeRect.left);

      const wrap = document.createElement('div');
      wrap.className = 'row-overlay ' + (kind || '');
      wrap.style.left = left + 'px';
      wrap.style.width = width + 'px';

      const inner = document.createElement('div');
      inner.className = 'row-overlay-text';
      inner.textContent = buildLongOverlayText(text);

      wrap.appendChild(inner);
      row.appendChild(wrap);
    });
  }

  // ✅ check_reports Promise (loadBlocks kutadi)
  function refreshReportStatusesAwaitable() {
    const filters = getFilterParams();

    const params = {
      action:      'check_reports',
      page:        currentPage,
      per_page:    perPage,
      product_id:  filters.product_id,
      category_id: filters.category_id,
      user_id:     filters.user_id,
      mode_type:   filters.mode_type,
      date_from:   filters.date_from,
      date_to:     filters.date_to,
      search:      filters.search
    };

    return asPromise(
      $.getJSON(apiUrl, params)
        .done(function (res) {
          if (res.status !== 'ok') return;

          const results = res.results || [];

          results.forEach(r => {
            const row = $('#blocks-table tbody tr[data-id="' + r.id + '"]');
            if (!row.length) return;

            row.attr('data-status-severity', r.severity || '');
            row.attr('data-status-text', r.status_text || '');

            const severity  = r.severity || '';
            const totalCodes = Number(row.attr('data-total-codes') || 0);
            const soldCodes  = Number(row.attr('data-sold-codes') || 0);
            const isFullSold = (row.attr('data-is-fullsold') === '1');

            // ✅ overlay matn/kind
            let overlayText = '';
            let overlayKind = '';

            if (isFullSold) {
              overlayText = `Sotilgan: ${soldCodes}/${totalCodes}`;
              overlayKind = 'sold';
            }

            if (severity === 'error') {
              overlayText = overlayText ? (overlayText + ' | Xatolik') : 'Xatolik';
              overlayKind = isFullSold ? 'sold_error' : 'error';
            } else if (severity === 'warning') {
              overlayText = overlayText ? (overlayText + ' | Ogohlantirish') : 'Ogohlantirish';
              overlayKind = isFullSold ? 'sold_warning' : 'warning';
            }

            row.attr('data-overlay-text', overlayText);
            row.attr('data-overlay-kind', overlayKind);

            // ✅ overlay chizish
            applyRowOverlayFromCodeToAction(r.id, overlayText, overlayKind);

            // ✅ GTIN ustuni ichida badge-lar (faqat FULL sold)
            const badgeContainer = $('[data-status-badges-for="' + r.id + '"]');
            if (!badgeContainer.length) return;

            let saleBadge = '';
            if (isFullSold) {
              saleBadge = `<span class="sale-lite"><i class="fa-solid fa-check"></i> Sotilgan: ${soldCodes}/${totalCodes}</span>`;
            }

            let xtraceBadge = '';
            if (severity === 'error') {
              xtraceBadge = `<span class="status-pill bg-danger-subtle text-danger"><i class="fa-solid fa-triangle-exclamation"></i> Xtrace xatolik</span>`;
            } else if (severity === 'warning') {
              xtraceBadge = `<span class="status-pill bg-warning-subtle text-warning"><i class="fa-solid fa-circle-exclamation"></i> Xtrace ogohlantirish</span>`;
            } else if (severity === 'ok') {
              xtraceBadge = `<span class="status-pill bg-success-subtle text-success"><i class="fa-solid fa-circle-check"></i> Xtrace OK</span>`;
            }

            badgeContainer.html(saleBadge + xtraceBadge);

            // tooltip
            const codeCell = row.find('td').eq(3);
            if (r.status_text) codeCell.attr('title', r.status_text);
          });

          applyStatusFilter();
        })
    );
  }

  // ✅ Status filtr (sold = faqat FULL sold)
  function applyStatusFilter() {
    const val = $('#filter_status').val();

    $('#blocks-table tbody tr').each(function () {
      const row = $(this);
      const isFullSold = row.attr('data-is-fullsold') === '1';
      const severity = row.attr('data-status-severity') || '';

      let show = true;

      if (val === 'sold') {
        show = isFullSold;
      } else if (val === 'error') {
        show = severity === 'error';
      } else if (val === 'sold_error') {
        show = isFullSold && (severity === 'error');
      }

      row.toggle(show);
    });
  }

  // ✅ resize bo‘lsa overlay qayta chizilsin
  window.addEventListener('resize', () => {
    $('#blocks-table tbody tr').each(function(){
      const id = $(this).attr('data-id');
      const txt = $(this).attr('data-overlay-text') || '';
      const kind = $(this).attr('data-overlay-kind') || '';
      if (id && txt) applyRowOverlayFromCodeToAction(id, txt, kind);
    });
  });

  // --- Modal ochish va kodlar ---
  function openDetails(blockId) {
    const b = (lastResponse || []).find(r => Number(r.id) === Number(blockId));
    if (!b) {
      toastr.error('Blok ma\'lumotlari topilmadi');
      return;
    }

    currentBlockDetails = {
      ...b,
      codes: [],
      summary: {},
      integrity_errors: [],
      xtrace_status: null
    };

    $('#details_block_id').text('#' + b.id);
    $('#details_product_name').text(b.product_name || '');
    $('#details_category_name').text(b.category_name || '');
    $('#details_code').text(b.gtin2_number || '');
    $('#details_mode').text(b.mode_type || '');
    $('#details_user').text(b.user_name || '');
    $('#details_report_id').text(b.report_id || '');
    $('#details_created').text(b.created_at || '');

    $('#details_xtrace_status_box').html('');
    $('#details_integrity_box').html('');
    $('#details_codes_container').html('<div class="text-muted small">Yuklanmoqda...</div>');

    const imgSrc = b.product_image ? withBase(b.product_image) : '';
    if (imgSrc) {
      $('#details_image').attr('src', imgSrc).show();
    } else {
      $('#details_image').hide();
    }

    const modalEl = document.getElementById('blockDetailsModal');
    const modal   = bootstrap.Modal.getOrCreateInstance(modalEl);
    modal.show();

    showGlobalLoading("Blok ma'lumotlari...", "Kodlar yuklanmoqda");

    $.getJSON(apiUrl, {action: 'block_codes', block_id: b.id})
      .done(function (res) {
        if (res.status !== 'ok') {
          $('#details_codes_container').html(
            '<div class="text-danger small">Kodlarni yuklashda xatolik: ' +
              escapeHtml(res.message || 'Xatolik') + '</div>'
          );
          return;
        }

        currentBlockDetails.codes            = res.codes || [];
        currentBlockDetails.summary          = res.summary || {};
        currentBlockDetails.integrity_errors = res.integrity_errors || [];
        currentBlockDetails.xtrace_status    = res.report_status || null;

        renderXtraceAndIntegrity();
        renderDetailsCodes();
      })
      .fail(function () {
        $('#details_codes_container').html(
          '<div class="text-danger small">Kodlarni yuklashda server xatosi</div>'
        );
      })
      .always(function(){
        hideGlobalLoading();
      });
  }

  function renderXtraceAndIntegrity() {
    const xs   = currentBlockDetails.xtrace_status || null;
    const errs = currentBlockDetails.integrity_errors || [];
    const summary = currentBlockDetails.summary || {};

    if (xs && xs.status_text) {
      let cls = 'alert-info';
      if (xs.severity === 'ok')       cls = 'alert-success';
      else if (xs.severity === 'warning') cls = 'alert-warning';
      else if (xs.severity === 'error')   cls = 'alert-danger';

      const html = `
        <div class="alert ${cls} small mb-2">
          <div class="fw-semibold mb-1">
            <i class="fa-solid fa-file-circle-check me-1"></i> Xtrace holati:
          </div>
          <div>${escapeHtml(xs.status_text || '-')}</div>
        </div>
      `;
      $('#details_xtrace_status_box').html(html);
    } else {
      $('#details_xtrace_status_box').html('');
    }

    if (errs.length) {
      let html = `
        <div class="alert alert-danger small mb-2">
          <div class="fw-semibold mb-1">
            <i class="fa-solid fa-triangle-exclamation me-1"></i> Ushbu blok bo‘yicha xatoliklar mavjud.
          </div>
          <ul class="mb-0">
      `;
      errs.forEach(e => {
        html += `<li>${escapeHtml(e.message || '')}</li>`;
      });
      html += '</ul></div>';

      $('#details_integrity_box').html(html);
    } else {
      $('#details_integrity_box').html('');
    }

    if (summary && summary.expected_codes != null) {
      const sold  = summary.sold_codes || 0;
      const total = summary.expected_codes || 0;
      const html = `
        <div class="alert alert-secondary small mb-0">
          <div class="fw-semibold mb-1">
            <i class="fa-solid fa-barcode me-1"></i> Kodlar statistikasi
          </div>
          <div>Jami kodlar: <b>${total}</b>, shundan sotilgan: <b>${sold}</b></div>
        </div>
      `;
      $('#details_integrity_box').append(html);
    }
  }

  function renderDetailsCodes() {
    const details = currentBlockDetails || {};
    const codes   = details.codes || [];

    if (!codes.length) {
      $('#details_codes_container').html(
        '<div class="text-muted small">Bu blok uchun iste\'mol kodlari topilmadi</div>'
      );
      return;
    }

    let html = '<div class="table-responsive"><table class="table table-sm table-striped mb-0">';
    html += `
      <thead>
        <tr>
          <th>#</th>
          <th>GS1 matn</th>
          <th>Vaqt</th>
          <th>Status</th>
          <th>Sotuv ma\'lumotlari</th>
          <th>Xatoliklar</th>
        </tr>
      </thead>
      <tbody>
    `;

    codes.forEach(c => {
      const isSold  = !!c.is_sold;
      const issues  = c.issues || [];
      const hasIssue = issues.length > 0;

      let rowClass = '';
      if (hasIssue) rowClass = 'code-row-issue';
      if (isSold)   rowClass = (rowClass ? rowClass + ' ' : '') + 'code-row-sold';

      let statusHtml = '<span class="badge bg-secondary-subtle text-secondary code-sale-badge">Bo‘sh (sotilmagan)</span>';
      if (isSold) {
        statusHtml = '<span class="badge bg-success-subtle text-success code-sale-badge"><i class="fa-solid fa-check me-1"></i>Sotilgan</span>';
      }

      let saleHtml = '<span class="text-muted small">Sotilmagan</span>';
      if (isSold) {
        const cust = c.sale_customer_full_name || c.sale_customer_name || '';
        const op   = c.sale_user_name || '';
        const dt   = c.sale_date || c.sale_created_at || '';
        saleHtml = `
          <div class="small">
            <div><strong>Mijoz:</strong> ${escapeHtml(cust || '-')}</div>
            <div><strong>Sana:</strong> ${escapeHtml(dt || '-')}</div>
            <div><strong>Operator:</strong> ${escapeHtml(op || '-')}</div>
            <div><strong>Sotuv ID:</strong> ${c.sale_id ? escapeHtml(String(c.sale_id)) : '-'}</div>
          </div>
        `;
      }

      let issuesHtml = '<span class="text-muted small">Xatolik yo‘q</span>';
      if (hasIssue) {
        issuesHtml = '<ul class="small text-danger mb-0">';
        issues.forEach(i => {
          issuesHtml += `<li>${escapeHtml(i)}</li>`;
        });
        issuesHtml += '</ul>';
      }

      html += `
        <tr class="${rowClass}">
          <td>${c.id}</td>
          <td><code>${escapeHtml(c.gs1_text || '')}</code></td>
          <td class="small text-muted">${escapeHtml(c.created_at || '')}</td>
          <td>${statusHtml}</td>
          <td>${saleHtml}</td>
          <td>${issuesHtml}</td>
        </tr>
      `;
    });

    html += '</tbody></table></div>';
    $('#details_codes_container').html(html);
  }

  function exportBlockDetails(format) {
    if (!currentBlockDetails) {
      toastr.error('Blok tanlanmagan');
      return;
    }

    if (format === 'pdf' || format === 'png' || format === 'jpg') {
      const el = document.getElementById('blockDetailsContent');
      showGlobalLoading("Export...", "Blok rasmi/PDF tayyorlanmoqda");
      html2canvas(el).then(canvas => {
        if (format === 'pdf') {
          const { jsPDF } = window.jspdf;
          const imgData = canvas.toDataURL('image/png');
          const pdf = new jsPDF('p', 'pt', [canvas.width, canvas.height]);
          pdf.addImage(imgData, 'PNG', 0, 0, canvas.width, canvas.height);
          pdf.save('block_' + currentBlockDetails.id + '.pdf');
        } else {
          const mime = format === 'jpg' ? 'image/jpeg' : 'image/png';
          canvas.toBlob(function (blob) {
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = 'block_' + currentBlockDetails.id + (format === 'jpg' ? '.jpg' : '.png');
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
          }, mime);
        }
      }).finally(() => {
        hideGlobalLoading();
      });
      return;
    }

    const b = currentBlockDetails;
    const header = [
      'BlockID','Mahsulot','Kategoriya','GTIN2/SSCC18','Mode',
      'Foydalanuvchi','ReportID','CreatedAt'
    ];
    const metaLine = [
      b.id,
      (b.product_name  || '').replace(/;/g, ','),
      (b.category_name || '').replace(/;/g, ','),
      (b.gtin2_number  || '').replace(/;/g, ','),
      b.mode_type,
      (b.user_name || '').replace(/;/g, ','),
      b.report_id || '',
      b.created_at || ''
    ];

    const lines = [];
    lines.push(header.join(';'));
    lines.push(metaLine.join(';'));
    lines.push('');
    lines.push('BlockCodeID;GS1_text;CreatedAt;IsSold;SaleID;Customer;Operator;Issues');

    (b.codes || []).forEach(c => {
      const issuesStr = (c.issues || []).join(', ');
      lines.push([
        c.id,
        (c.gs1_text || '').replace(/;/g, ','),
        c.created_at || '',
        c.is_sold ? 1 : 0,
        c.sale_id || '',
        ((c.sale_customer_full_name || c.sale_customer_name || '')).replace(/;/g, ','),
        (c.sale_user_name || '').replace(/;/g, ','),
        issuesStr.replace(/;/g, ',')
      ].join(';'));
    });

    const csv = lines.join('\r\n');
    const extMap = {csv:'csv', xls:'xls', xlsx:'xlsx', doc:'doc'};
    const ext = extMap[format] || 'csv';
    const filename = `block_${b.id}_details.${ext}`;
    downloadTextFile(csv, filename);
  }

  function escapeHtml(str) {
    if (!str) return '';
    return String(str)
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
  }

  window.exportBlockDetails = exportBlockDetails;
  window.openDetails        = openDetails;
  window.deleteBlock        = deleteBlock;
</script>
</body>
</html>
