<?php
require_once __DIR__ . '/includes/db.php';
require_once __DIR__ . '/includes/receptions.php';

$pageTitle  = 'Generare recepție';
$breadcrumb = [['label' => 'Generare recepție']];

// Scopul = contul activ (selectat din header). 0 = toate conturile.
$filterAccount = active_account_id();

$products = [];
$receptions = [];
$dbError  = null;

try {
    // Doar produsele ACTIVE pe eMAG (emag_offer_status = 1). La FBE trimitem
    // doar ofertele pornite.
    $where  = ['p.emag_offer_status = 1'];
    $params = [];
    if ($filterAccount > 0) {
        $where[] = 'p.emag_account_id = ?';
        $params[] = $filterAccount;
    }
    $whereSql = implode(' AND ', $where);

    // `fbe_stock` = stocul curent din depozitul FBE (citit de pe eMAG la ultimul
    // sync) pentru produsul cu același EAN dintr-un cont marcat is_fbe = 1.
    $products = db_select(
        "SELECT p.id, p.ean, p.product_name, p.custom_name, p.pnk,
                p.phone_series_id, p.units_per_box,
                (SELECT pb.name || ' ' || pm.name || ' ' || ps.name
                 FROM phone_series ps
                 JOIN phone_models pm ON pm.id = ps.model_id
                 JOIN phone_brands pb ON pb.id = pm.brand_id
                 WHERE ps.id = p.phone_series_id) AS phone_label,
                (SELECT pf.current_stock FROM products pf
                 JOIN emag_accounts af ON af.id = pf.emag_account_id
                 WHERE af.is_fbe = 1 AND pf.ean IS NOT NULL AND pf.ean = p.ean
                 ORDER BY pf.id LIMIT 1) AS fbe_stock,
                a.account_name
         FROM products p
         LEFT JOIN emag_accounts a ON a.id = p.emag_account_id
         WHERE $whereSql
         ORDER BY (p.custom_name IS NULL), p.custom_name COLLATE NOCASE,
                  p.product_name COLLATE NOCASE",
        $params
    );

    // Sesiunile de recepție salvate (cu items atașate, în ordine).
    $receptions = db_select(
        "SELECT r.*,
                (SELECT COUNT(*) FROM fbe_reception_items WHERE reception_id = r.id) AS items_count,
                (SELECT COALESCE(SUM(qty),0) FROM fbe_reception_items WHERE reception_id = r.id) AS total_qty
         FROM fbe_receptions r
         ORDER BY r.created_at DESC"
    );
    foreach ($receptions as &$r) {
        $r['items'] = reception_items((int)$r['id']);
    }
    unset($r);
} catch (Throwable $ex) {
    $dbError = $ex->getMessage();
}

require __DIR__ . '/includes/header.php';
?>

<!-- SheetJS pentru generarea fișierului Excel (.xlsx) -->
<script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>

<?php if ($dbError): ?>
  <div class="mb-6 bg-amber-50 border border-amber-200 rounded-xl p-4 text-sm text-amber-900">
    Eroare DB. <details class="mt-2"><summary class="cursor-pointer">Detalii</summary><pre class="mt-2 text-xs"><?= e($dbError) ?></pre></details>
  </div>
<?php endif; ?>

<div
  x-data="receptiePage({
    rows: <?= htmlspecialchars(json_encode($products), ENT_QUOTES, 'UTF-8') ?>,
    sessions: <?= htmlspecialchars(json_encode($receptions), ENT_QUOTES, 'UTF-8') ?>,
    accountId: <?= (int)$filterAccount ?>,
    csrf: '<?= e(csrf_token()) ?>'
  })"
>

  <!-- ================= VEDERE LISTĂ (istoric sesiuni) ================= -->
  <div x-show="view === 'list'">
    <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6">
      <div>
        <h1 class="text-2xl font-bold text-slate-900">Recepții FBE</h1>
        <p class="text-sm text-slate-500 mt-0.5"><span x-text="sessions.length"></span> sesiuni salvate</p>
      </div>
      <button @click="openNewSession()"
        class="inline-flex items-center gap-2 px-3.5 py-2 text-sm font-medium text-white bg-brand-600 hover:bg-brand-700 rounded-lg shadow-soft transition">
        <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/></svg>
        Generează sesiune nouă
      </button>
    </div>

    <div class="bg-white border border-slate-100 rounded-xl shadow-soft overflow-hidden">
      <div class="overflow-x-auto">
        <table class="text-sm w-full">
          <thead class="bg-slate-50 text-xs uppercase tracking-wide text-slate-500">
            <tr class="divide-x divide-slate-200">
              <th class="px-3 py-2.5 text-left font-medium w-10">#</th>
              <th class="px-3 py-2.5 text-left font-medium">Nume</th>
              <th class="px-3 py-2.5 text-left font-medium whitespace-nowrap">Nr. recepție</th>
              <th class="px-3 py-2.5 text-right font-medium whitespace-nowrap">Produse</th>
              <th class="px-3 py-2.5 text-right font-medium whitespace-nowrap">Total buc.</th>
              <th class="px-3 py-2.5 text-left font-medium whitespace-nowrap">Creată</th>
              <th class="px-3 py-2.5 text-right font-medium w-40">Acțiuni</th>
            </tr>
          </thead>
          <tbody class="divide-y divide-slate-100">
            <template x-if="sessions.length === 0">
              <tr><td colspan="7" class="px-4 py-12 text-center text-slate-400">
                Nicio sesiune salvată încă. Apasă <span class="font-medium text-slate-600">„Generează sesiune nouă"</span> ca să începi.
              </td></tr>
            </template>
            <template x-for="(s, idx) in sessions" :key="s.id">
              <tr class="row-hover divide-x divide-slate-100">
                <td class="px-3 py-2.5 text-xs text-slate-400 font-mono tabular-nums" x-text="idx + 1"></td>
                <td class="px-3 py-2.5 text-slate-800 font-medium">
                  <button @click="editSession(s)" class="hover:text-brand-600 transition text-left" x-text="s.name"></button>
                </td>
                <td class="px-3 py-2.5">
                  <span x-show="s.reception_number" class="inline-block font-mono text-xs bg-slate-100 text-slate-700 px-1.5 py-0.5 rounded" x-text="s.reception_number"></span>
                  <span x-show="!s.reception_number" class="text-slate-300">—</span>
                </td>
                <td class="px-3 py-2.5 text-right tabular-nums text-slate-600" x-text="s.items_count"></td>
                <td class="px-3 py-2.5 text-right tabular-nums font-semibold text-slate-800" x-text="s.total_qty"></td>
                <td class="px-3 py-2.5 text-xs text-slate-500 whitespace-nowrap" x-text="formatDate(s.created_at)"></td>
                <td class="px-3 py-2.5 text-right whitespace-nowrap">
                  <a :href="'<?= url('impachetare.php') ?>?id=' + s.id" class="inline-block text-sky-600 hover:text-sky-700 p-1.5 rounded hover:bg-sky-50 transition" title="Pagina de împachetare">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>
                  </a>
                  <button @click="editSession(s)" class="text-brand-600 hover:text-brand-700 p-1.5 rounded hover:bg-brand-50 transition" title="Editează sesiunea">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"/></svg>
                  </button>
                  <button @click="downloadSession(s)" class="text-emerald-700 hover:text-emerald-800 p-1.5 rounded hover:bg-emerald-50 transition" title="Descarcă Excel recepție">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5 5 5-5M12 15V3"/></svg>
                  </button>
                  <button @click="downloadPacking(s)" class="text-indigo-600 hover:text-indigo-700 p-1.5 rounded hover:bg-indigo-50 transition" title="Descarcă Excel împachetare">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"/></svg>
                  </button>
                  <button @click="deleteSession(s)" class="text-rose-600 hover:text-rose-700 p-1.5 rounded hover:bg-rose-50 transition" title="Șterge sesiunea">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6M1 7h22M9 7V4a1 1 0 011-1h4a1 1 0 011 1v3"/></svg>
                  </button>
                </td>
              </tr>
            </template>
          </tbody>
        </table>
      </div>
    </div>
  </div>

  <!-- ================= VEDERE EDITOR (produse + lista sesiunii) ================= -->
  <div x-show="view === 'editor'" x-cloak>
    <!-- Header sesiune -->
    <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6">
      <div class="flex items-center gap-3 min-w-0">
        <button @click="backToList()" class="flex-shrink-0 inline-flex items-center justify-center w-9 h-9 text-slate-500 hover:text-brand-600 hover:bg-slate-100 rounded-lg transition" title="Înapoi la listă">
          <svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"/></svg>
        </button>
        <div class="min-w-0">
          <h1 class="text-2xl font-bold text-slate-900 truncate" x-text="currentSession.name"></h1>
          <p class="text-sm text-slate-500 mt-0.5 truncate flex items-center gap-2">
            <span x-show="currentSession.reception_number">Nr. <span class="font-mono" x-text="currentSession.reception_number"></span> ·</span>
            <span><span class="font-medium text-slate-700" x-text="items.length"></span> produse · <span class="font-medium text-slate-700" x-text="totalPieces()"></span> bucăți</span>
            <!-- status autosave -->
            <span class="inline-flex items-center gap-1.5">
              <template x-if="saveState === 'saving'">
                <span class="inline-flex items-center gap-1.5 text-brand-600"><span class="spinner"></span> se salvează…</span>
              </template>
              <template x-if="saveState === 'saved'">
                <span class="inline-flex items-center gap-1 text-emerald-600">
                  <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>
                  salvat
                </span>
              </template>
              <template x-if="saveState === 'error'">
                <span class="inline-flex items-center gap-1 text-rose-600" :title="saveError">
                  <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg>
                  eroare la salvare
                </span>
              </template>
            </span>
          </p>
        </div>
      </div>
      <div class="flex items-center gap-2 flex-shrink-0">
        <button @click="editDetails()" class="inline-flex items-center gap-2 px-3.5 py-2 text-sm font-medium text-slate-700 bg-white border border-slate-200 hover:bg-slate-50 rounded-lg shadow-soft transition" title="Editează nume / nr. recepție">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"/></svg>
          Detalii
        </button>
        <a x-show="currentSession.id" :href="'<?= url('impachetare.php') ?>?id=' + currentSession.id"
          class="inline-flex items-center gap-2 px-3.5 py-2 text-sm font-medium text-sky-700 bg-sky-50 border border-sky-100 hover:bg-sky-100 rounded-lg shadow-soft transition" title="Deschide pagina de împachetare">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>
          Împachetare
        </a>
        <button @click="generateExcel()" :disabled="items.length === 0"
          class="inline-flex items-center gap-2 px-3.5 py-2 text-sm font-medium text-emerald-700 bg-emerald-50 border border-emerald-100 hover:bg-emerald-100 rounded-lg shadow-soft transition disabled:opacity-50 disabled:cursor-not-allowed">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5 5 5-5M12 15V3"/></svg>
          Excel recepție
        </button>
        <button @click="generatePacking()" :disabled="items.length === 0"
          class="inline-flex items-center gap-2 px-3.5 py-2 text-sm font-medium text-indigo-700 bg-indigo-50 border border-indigo-100 hover:bg-indigo-100 rounded-lg shadow-soft transition disabled:opacity-50 disabled:cursor-not-allowed"
          title="Export pentru împachetare (nume + numărătoare, produsele legate grupate)">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"/></svg>
          Excel împachetare
        </button>
      </div>
    </div>

    <div class="grid grid-cols-1 lg:grid-cols-5 gap-6">

      <!-- ============ STÂNGA: catalog produse + adăugare în listă ============ -->
      <div class="lg:col-span-3 bg-white border border-slate-100 rounded-xl shadow-soft flex flex-col">
        <div class="px-4 py-3 border-b border-slate-100">
          <div class="flex items-center justify-between gap-3">
            <h2 class="font-semibold text-slate-900">1. Alege produsele și câte bucăți trimiți</h2>
            <label class="inline-flex items-center gap-2 text-xs text-slate-600 cursor-pointer select-none">
              <input type="checkbox" x-model="hideAdded" class="rounded border-slate-300 text-brand-600 focus:ring-brand-500">
              Ascunde ce e deja în listă
            </label>
          </div>
          <div class="relative mt-2">
            <svg class="w-4 h-4 absolute left-3 top-2.5 text-slate-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
            <input type="text" x-model="search" placeholder="Caută după nume, EAN, PNK…" autocomplete="off"
              class="w-full pl-9 pr-3 py-2 text-sm border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent">
          </div>
        </div>

        <div class="overflow-x-auto max-h-[70vh] overflow-y-auto">
          <table class="text-sm w-full">
            <thead class="bg-slate-50 text-xs uppercase tracking-wide text-slate-500 sticky top-0 z-10">
              <tr class="divide-x divide-slate-200">
                <th class="px-2 py-2.5 text-left font-medium w-10">#</th>
                <th class="px-3 py-2.5 text-left font-medium">Produs</th>
                <th class="px-3 py-2.5 text-left font-medium whitespace-nowrap">EAN</th>
                <th class="px-3 py-2.5 text-right font-medium whitespace-nowrap w-24" title="Stocul curent din depozitul FBE (de la ultimul sync)">Stoc FBE</th>
                <th class="px-3 py-2.5 text-right font-medium w-40">Bucăți FBE</th>
              </tr>
            </thead>
            <tbody class="divide-y divide-slate-100">
              <template x-if="filteredRows().length === 0">
                <tr><td colspan="5" class="px-4 py-12 text-center text-slate-400">Niciun produs activ nu corespunde căutării.</td></tr>
              </template>
              <template x-for="(p, idx) in filteredRows()" :key="p.id">
                <tr class="row-hover align-top divide-x divide-slate-100"
                    :class="inListQty(p) !== null ? 'bg-emerald-50/40' : ''">
                  <td class="px-2 py-2 align-top text-xs text-slate-400 font-mono tabular-nums" x-text="idx + 1"></td>
                  <td class="px-3 py-2 align-top">
                    <div class="text-slate-800 break-words leading-snug"
                         :title="p.custom_name || p.product_name"
                         x-text="shortName(p.custom_name || p.product_name)"></div>
                    <div class="flex items-center gap-2 mt-0.5">
                      <span class="text-[10px] text-slate-400 font-mono" x-show="p.pnk" x-text="p.pnk"></span>
                      <span x-show="inListQty(p) !== null"
                            class="text-[10px] font-medium text-emerald-700 bg-emerald-100 px-1.5 py-0.5 rounded"
                            x-text="'în listă: ' + (inListQty(p) ?? 0) + ' buc'"></span>
                    </div>
                  </td>
                  <td class="px-3 py-2 align-top">
                    <span class="font-mono text-xs text-slate-600" x-text="p.ean || '—'"></span>
                  </td>
                  <td class="px-3 py-2 align-top text-right tabular-nums">
                    <span x-show="p.fbe_stock === null" class="text-slate-300">—</span>
                    <span x-show="p.fbe_stock !== null"
                          class="inline-block px-1.5 py-0.5 rounded text-xs font-semibold"
                          :class="Number(p.fbe_stock) === 0 ? 'bg-rose-100 text-rose-700'
                                  : (Number(p.fbe_stock) <= 5 ? 'bg-amber-100 text-amber-700' : 'bg-slate-100 text-slate-700')"
                          x-text="p.fbe_stock"></span>
                  </td>
                  <td class="px-3 py-2 align-top text-right">
                    <div class="inline-flex items-center gap-1.5 justify-end">
                      <input type="number" min="0" step="1" placeholder="buc"
                        x-model="addQty[p.id]"
                        @keydown.enter.prevent="addToList(p)"
                        class="w-16 px-2 py-1 text-sm text-right border border-slate-200 rounded focus:outline-none focus:ring-2 focus:ring-brand-500 tabular-nums">
                      <button @click="addToList(p)" :disabled="addingIds.includes(p.id)"
                        class="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-white bg-brand-600 hover:bg-brand-700 rounded transition disabled:opacity-50"
                        title="Adaugă în lista sesiunii">
                        <span x-show="addingIds.includes(p.id)" class="spinner"></span>
                        <svg x-show="!addingIds.includes(p.id)" class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/></svg>
                        Add
                      </button>
                    </div>
                  </td>
                </tr>
              </template>
            </tbody>
          </table>
        </div>
      </div>

      <!-- ============ DREAPTA: lista sesiunii ============ -->
      <div class="lg:col-span-2 space-y-4">
        <div class="bg-white border border-slate-100 rounded-xl shadow-soft">
          <div class="px-4 py-3 border-b border-slate-100 flex items-center justify-between gap-3">
            <h2 class="font-semibold text-slate-900">2. Lista recepției</h2>
            <button @click="clearList()" x-show="items.length > 0"
              class="text-xs text-rose-600 hover:text-rose-700 hover:underline">Golește lista</button>
          </div>

          <div class="max-h-[52vh] overflow-y-auto">
            <table class="text-sm w-full">
              <thead class="bg-slate-50 text-xs uppercase tracking-wide text-slate-500 sticky top-0 z-10">
                <tr class="divide-x divide-slate-200">
                  <th class="px-2 py-2 text-left font-medium w-8">#</th>
                  <th class="px-2 py-2 text-left font-medium">Produs</th>
                  <th class="px-2 py-2 text-right font-medium w-14" title="Stoc curent FBE">Stoc</th>
                  <th class="px-2 py-2 text-right font-medium w-20">Bucăți</th>
                  <th class="px-2 py-2 w-8"></th>
                </tr>
              </thead>
              <tbody class="divide-y divide-slate-100">
                <template x-if="items.length === 0">
                  <tr><td colspan="5" class="px-4 py-10 text-center text-slate-400 text-sm">
                    Lista e goală. Adaugă produse din tabelul din stânga cu butonul <span class="font-medium text-slate-600">Add</span>.
                  </td></tr>
                </template>
                <template x-for="(it, idx) in items" :key="it.id">
                  <tr class="row-hover align-top divide-x divide-slate-100">
                    <td class="px-2 py-2 text-xs text-slate-400 font-mono tabular-nums" x-text="idx + 1"></td>
                    <td class="px-2 py-2">
                      <div class="text-slate-800 text-xs leading-snug break-words" :title="itemName(it)" x-text="shortName(itemName(it), 45)"></div>
                      <div class="text-[10px] text-slate-400 font-mono mt-0.5" x-text="it.ean || '—'"></div>
                    </td>
                    <td class="px-2 py-2 text-right tabular-nums text-xs">
                      <span x-show="it.fbe_stock === null" class="text-slate-300">—</span>
                      <span x-show="it.fbe_stock !== null"
                            :class="Number(it.fbe_stock) === 0 ? 'text-rose-600 font-semibold' : 'text-slate-600'"
                            x-text="it.fbe_stock"></span>
                    </td>
                    <td class="px-2 py-2 text-right">
                      <div class="inline-flex items-center gap-1">
                        <input type="number" min="0" step="1"
                          :value="it.qty ?? ''"
                          @change="setQty(it, $event.target.value)"
                          @keydown.enter.prevent="$event.target.blur()"
                          class="w-16 px-1.5 py-1 text-sm text-right border rounded focus:outline-none focus:ring-2 focus:ring-brand-500 tabular-nums"
                          :class="(it.qty != null && it.qty !== '') ? 'border-emerald-300 bg-emerald-50' : 'border-amber-300 bg-amber-50'">
                        <span x-show="savingItemIds.includes(it.id)" class="spinner"></span>
                      </div>
                    </td>
                    <td class="px-2 py-2 text-center">
                      <button @click="removeItem(it)" class="text-slate-300 hover:text-rose-600 transition" title="Scoate din listă">
                        <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
                      </button>
                    </td>
                  </tr>
                </template>
              </tbody>
            </table>
          </div>

          <!-- Sumar -->
          <div class="px-4 py-3 border-t border-slate-100 grid grid-cols-3 gap-2 text-center">
            <div class="bg-slate-50 rounded-lg py-2">
              <div class="text-lg font-bold text-slate-800 tabular-nums" x-text="items.length"></div>
              <div class="text-[10px] uppercase tracking-wide text-slate-400">produse</div>
            </div>
            <div class="bg-emerald-50 rounded-lg py-2">
              <div class="text-lg font-bold text-emerald-700 tabular-nums" x-text="totalPieces()"></div>
              <div class="text-[10px] uppercase tracking-wide text-emerald-600">bucăți</div>
            </div>
            <div class="bg-amber-50 rounded-lg py-2">
              <div class="text-lg font-bold text-amber-700 tabular-nums" x-text="missingQtyItems().length"></div>
              <div class="text-[10px] uppercase tracking-wide text-amber-600">fără cantitate</div>
            </div>
          </div>
        </div>

        <!-- Adăugare rapidă prin lipire EAN-uri -->
        <div class="bg-white border border-slate-100 rounded-xl shadow-soft">
          <button @click="bulkOpen = !bulkOpen"
            class="w-full px-4 py-3 flex items-center justify-between text-left">
            <span class="font-medium text-slate-800 text-sm">Adaugă mai multe deodată (lipește EAN-uri)</span>
            <svg class="w-4 h-4 text-slate-400 transition" :class="bulkOpen ? 'rotate-180' : ''" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/></svg>
          </button>
          <div x-show="bulkOpen" x-cloak class="px-4 pb-4">
            <p class="text-xs text-slate-500 mb-2">Un EAN pe linie. Opțional cantitatea după virgulă sau spațiu: <span class="font-mono">5901234567890, 12</span></p>
            <textarea x-model="bulkText" rows="6" spellcheck="false"
              placeholder="5901234567890, 12&#10;4006381333931 5&#10;…"
              class="w-full px-3 py-2 text-sm font-mono border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500 resize-y"></textarea>
            <button @click="addBulk()" :disabled="bulkSaving || bulkText.trim() === ''"
              class="mt-2 inline-flex items-center gap-2 px-3 py-2 text-sm font-medium text-white bg-brand-600 hover:bg-brand-700 rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed">
              <span x-show="bulkSaving" class="spinner"></span>
              Adaugă în listă
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- ============ MODAL: detalii sesiune (id de sesiune) ============ -->
  <div x-show="detailsModalOpen" x-cloak @keydown.escape.window="detailsModalOpen = false"
       class="fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/50 backdrop-blur-sm"
       @mousedown.self="detailsModalOpen = false">
    <div class="modal-enter bg-white rounded-2xl shadow-2xl w-full max-w-md">
      <div class="px-6 py-4 border-b border-slate-100 flex items-center justify-between">
        <h3 class="font-semibold text-slate-900" x-text="detailsMode === 'new' ? 'Sesiune nouă de recepție' : 'Detalii sesiune'"></h3>
        <button type="button" @click="detailsModalOpen = false" class="text-slate-400 hover:text-slate-600 p-1">
          <svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
        </button>
      </div>
      <div class="p-6 space-y-4">
        <!-- Sesiune nouă: doar id-ul (numele se generează automat) -->
        <template x-if="detailsMode === 'new'">
          <div>
            <label class="block text-xs font-medium text-slate-700 mb-1">Nr. recepție <span class="text-rose-500">*</span></label>
            <input type="text" x-model="formId" placeholder="ex: 241435" inputmode="numeric"
              @keydown.enter="confirmDetails()"
              class="w-full px-3 py-2 text-sm border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500 font-mono">
            <p class="text-[11px] text-slate-400 mt-1">
              Numele se generează automat: <span class="font-medium text-slate-500" x-text="formId.trim() ? autoName(formId.trim()) : 'Recepție <nr> · ' + new Date().toLocaleDateString('ro-RO')"></span>
            </p>
          </div>
        </template>
        <!-- Editare detalii: nume + nr. recepție -->
        <template x-if="detailsMode === 'edit'">
          <div class="space-y-4">
            <div>
              <label class="block text-xs font-medium text-slate-700 mb-1">Nume sesiune <span class="text-rose-500">*</span></label>
              <input type="text" x-model="formName" @keydown.enter="confirmDetails()"
                class="w-full px-3 py-2 text-sm border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500">
            </div>
            <div>
              <label class="block text-xs font-medium text-slate-700 mb-1">Nr. recepție</label>
              <input type="text" x-model="formRecNumber" placeholder="ex: 241435"
                @keydown.enter="confirmDetails()"
                class="w-full px-3 py-2 text-sm border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500 font-mono">
              <p class="text-[11px] text-slate-400 mt-1">Apare în Excel (numele fișierului).</p>
            </div>
          </div>
        </template>
      </div>
      <div class="px-6 py-4 border-t border-slate-100 flex items-center justify-end gap-2">
        <button type="button" @click="detailsModalOpen = false" class="px-4 py-2 text-sm font-medium text-slate-600 hover:text-slate-800 transition">Anulează</button>
        <button type="button" @click="confirmDetails()"
          :disabled="savingMeta || (detailsMode === 'new' ? formId.trim() === '' : formName.trim() === '')"
          class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-brand-600 hover:bg-brand-700 rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed">
          <span x-show="savingMeta" class="spinner"></span>
          <span x-text="detailsMode === 'new' ? 'Creează sesiunea' : 'Salvează detaliile'"></span>
        </button>
      </div>
    </div>
  </div>
</div>

<script>
function receptiePage({ rows, sessions, accountId, csrf }) {
  return {
    rows: rows || [],
    sessions: sessions || [],
    accountId: accountId || 0,
    csrf,
    view: 'list',                 // 'list' | 'editor'
    currentSession: { id: 0, name: '', reception_number: '' },
    items: [],                    // lista sesiunii curente (din DB)
    search: '',
    hideAdded: false,
    addQty: {},                   // câte bucăți adăugăm, per produs (input-ul din tabel)
    addingIds: [],
    savingItemIds: [],
    saveState: '',                // '' | 'saving' | 'saved' | 'error'
    saveError: '',
    bulkOpen: false,
    bulkText: '',
    bulkSaving: false,
    // modal detalii
    detailsModalOpen: false,
    detailsMode: 'new',           // 'new' | 'edit'
    savingMeta: false,
    formId: '',                   // nr. recepție introdus la sesiune nouă
    formName: '',
    formRecNumber: '',

    // ---- navigare vederi ----
    openNewSession() {
      this.detailsMode = 'new';
      this.formId = '';
      this.detailsModalOpen = true;
    },
    editDetails() {
      this.detailsMode = 'edit';
      this.formName = this.currentSession.name;
      this.formRecNumber = this.currentSession.reception_number || '';
      this.detailsModalOpen = true;
    },
    // Numele generat automat din nr. recepției + data de azi. Ex: „Recepție 241435 · 15.06.2026".
    autoName(id) {
      return 'Recepție ' + id + ' · ' + new Date().toLocaleDateString('ro-RO');
    },
    // Sesiunea se creează în DB IMEDIAT — de aici încolo totul se autosalvează.
    async confirmDetails() {
      if (this.savingMeta) return;
      let name, recNumber;
      if (this.detailsMode === 'new') {
        const id = this.formId.trim();
        if (id === '') return;
        name = this.autoName(id);
        recNumber = id;
      } else {
        name = this.formName.trim();
        if (name === '') return;
        recNumber = this.formRecNumber.trim();
      }
      this.savingMeta = true;
      try {
        const fd = new FormData();
        fd.append('csrf_token', this.csrf);
        fd.append('id', this.detailsMode === 'new' ? 0 : (this.currentSession.id || 0));
        fd.append('name', name);
        fd.append('reception_number', recNumber);
        fd.append('account_id', this.accountId);
        // fără câmpul `items` → lista existentă rămâne neatinsă
        const d = await this.post('<?= url('api/save-reception.php') ?>', fd);
        this.applySession(d.session);
        this.updateSessionInList(d.session);
        this.detailsModalOpen = false;
        if (this.detailsMode === 'new') {
          this.search = '';
          this.addQty = {};
          this.view = 'editor';
          window.scrollTo({ top: 0 });
        }
      } catch (e) {
        alert('Nu am putut salva sesiunea: ' + e.message);
      } finally {
        this.savingMeta = false;
      }
    },
    editSession(s) {
      this.currentSession = { id: s.id, name: s.name, reception_number: s.reception_number || '' };
      this.items = (s.items || []).map(x => ({ ...x }));
      this.addQty = {};
      this.search = '';
      this.saveState = '';
      this.view = 'editor';
      window.scrollTo({ top: 0 });
    },
    backToList() {
      this.view = 'list';
      this.search = '';
      this.saveState = '';
    },

    // ---- helper POST cu tratarea erorilor + status autosave ----
    async post(url, fd) {
      this.saveState = 'saving';
      try {
        const r = await fetch(url, { method: 'POST', body: fd, credentials: 'same-origin' });
        let d;
        try { d = await r.json(); }
        catch (_) { throw new Error('Răspuns invalid de la server (HTTP ' + r.status + ')'); }
        if (!d.ok) throw new Error(d.error || 'Eroare necunoscută');
        this.saveState = 'saved';
        this.saveError = '';
        return d;
      } catch (e) {
        this.saveState = 'error';
        this.saveError = e.message;
        throw e;
      }
    },
    // Sincronizează starea locală cu sesiunea întoarsă de server.
    applySession(s) {
      if (!s) return;
      this.currentSession = { id: s.id, name: s.name, reception_number: s.reception_number || '' };
      this.items = (s.items || []).map(x => ({ ...x }));
      this.updateSessionInList(s);
    },

    // ---- catalog produse ----
    shortName(s, max) {
      s = (s || '').toString();
      const n = max || 60;
      return s.length > n ? s.slice(0, n) + '…' : s;
    },
    itemName(it) {
      return it.custom_name || it.live_name || it.product_name || it.ean || '';
    },
    // Câte bucăți are deja produsul în lista sesiunii (null = nu e în listă).
    inListQty(p) {
      const it = this.items.find(x =>
        (x.product_id != null && Number(x.product_id) === Number(p.id)) ||
        (x.product_id == null && p.ean && x.ean === p.ean)
      );
      if (!it) return null;
      return (it.qty == null || it.qty === '') ? 0 : Number(it.qty);
    },
    filteredRows() {
      let r = this.rows;
      if (this.hideAdded) r = r.filter(p => this.inListQty(p) === null);
      const q = this.search.trim().toLowerCase();
      if (q) {
        r = r.filter(p =>
          (p.ean || '').toLowerCase().includes(q) ||
          (p.custom_name || p.product_name || '').toLowerCase().includes(q) ||
          (p.pnk || '').toLowerCase().includes(q)
        );
      }
      return r;
    },

    // ---- operații pe lista sesiunii (autosave) ----
    async addToList(p) {
      if (!this.currentSession.id) { alert('Sesiunea nu e creată încă.'); return; }
      if (this.addingIds.includes(p.id)) return;
      const raw = (this.addQty[p.id] ?? '').toString().trim();
      this.addingIds.push(p.id);
      try {
        const fd = new FormData();
        fd.append('csrf_token', this.csrf);
        fd.append('action', 'add');
        fd.append('reception_id', this.currentSession.id);
        fd.append('product_id', p.id);
        fd.append('ean', p.ean || '');
        fd.append('qty', raw);
        const d = await this.post('<?= url('api/reception-item.php') ?>', fd);
        this.applySession(d.session);
        this.addQty[p.id] = '';
      } catch (e) {
        alert('Nu am putut adăuga produsul: ' + e.message);
      } finally {
        this.addingIds = this.addingIds.filter(x => x !== p.id);
      }
    },
    async setQty(it, val) {
      if (this.savingItemIds.includes(it.id)) return;
      this.savingItemIds.push(it.id);
      try {
        const fd = new FormData();
        fd.append('csrf_token', this.csrf);
        fd.append('action', 'set_qty');
        fd.append('reception_id', this.currentSession.id);
        fd.append('item_id', it.id);
        fd.append('qty', (val ?? '').toString().trim());
        const d = await this.post('<?= url('api/reception-item.php') ?>', fd);
        this.applySession(d.session);
      } catch (e) {
        alert('Nu am putut salva cantitatea: ' + e.message);
      } finally {
        this.savingItemIds = this.savingItemIds.filter(x => x !== it.id);
      }
    },
    async removeItem(it) {
      try {
        const fd = new FormData();
        fd.append('csrf_token', this.csrf);
        fd.append('action', 'delete');
        fd.append('reception_id', this.currentSession.id);
        fd.append('item_id', it.id);
        const d = await this.post('<?= url('api/reception-item.php') ?>', fd);
        this.applySession(d.session);
      } catch (e) {
        alert('Nu am putut șterge rândul: ' + e.message);
      }
    },
    async clearList() {
      if (!confirm('Golești toată lista acestei sesiuni?')) return;
      try {
        const fd = new FormData();
        fd.append('csrf_token', this.csrf);
        fd.append('action', 'clear');
        fd.append('reception_id', this.currentSession.id);
        const d = await this.post('<?= url('api/reception-item.php') ?>', fd);
        this.applySession(d.session);
      } catch (e) {
        alert('Nu am putut goli lista: ' + e.message);
      }
    },
    async addBulk() {
      if (this.bulkSaving) return;
      this.bulkSaving = true;
      try {
        const fd = new FormData();
        fd.append('csrf_token', this.csrf);
        fd.append('action', 'add_bulk');
        fd.append('reception_id', this.currentSession.id);
        fd.append('text', this.bulkText);
        const d = await this.post('<?= url('api/reception-item.php') ?>', fd);
        this.applySession(d.session);
        this.bulkText = '';
        this.bulkOpen = false;
      } catch (e) {
        alert('Nu am putut adăuga lista: ' + e.message);
      } finally {
        this.bulkSaving = false;
      }
    },

    // ---- sumare ----
    totalPieces() {
      let t = 0;
      for (const it of this.items) {
        if (it.qty != null && it.qty !== '') t += Number(it.qty) || 0;
      }
      return t;
    },
    missingQtyItems() {
      return this.items.filter(it => it.qty == null || it.qty === '' || Number(it.qty) === 0);
    },

    // ---- export Excel ----
    buildExcel(items, recNumber) {
      if (typeof XLSX === 'undefined') { alert('Biblioteca de export nu s-a încărcat încă. Reîncearcă în câteva secunde.'); return; }
      if (!items || !items.length) { alert('Lista sesiunii e goală.'); return; }
      const rec = (recNumber || '').toString().trim();
      const aoa = [['EAN', 'Bucăți', 'Nr recepție']];
      for (const it of items) {
        const hasQty = (it.qty != null && it.qty !== '');
        const qty = hasQty ? Number(it.qty) : '';
        // Nr. recepție se pune doar pe rândurile cu cantitate (la fel ca bucățile).
        aoa.push([String(it.ean || ''), qty, hasQty ? rec : '']);
      }
      const ws = XLSX.utils.aoa_to_sheet(aoa);
      ws['!cols'] = [{ wch: 18 }, { wch: 10 }, { wch: 14 }];
      const wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws, 'Recepție FBE');
      const safe = (recNumber || '').toString().trim().replace(/[^\w.\-]+/g, '_');
      XLSX.writeFile(wb, 'receptie-fbe' + (safe ? '-' + safe : '') + '.xlsx');
    },
    generateExcel() {
      this.buildExcel(this.items, this.currentSession.reception_number);
    },
    downloadSession(s) {
      this.buildExcel(s.items || [], s.reception_number);
    },

    // Export pentru ÎMPACHETARE: nume produs + numărătoare, doar ce are cantitate,
    // cu produsele LEGATE (același model telefon = phone_series_id) grupate unul sub
    // altul ca să se vadă variantele împreună la împachetat.
    buildPackingExcel(items, recNumber) {
      if (typeof XLSX === 'undefined') { alert('Biblioteca de export nu s-a încărcat încă. Reîncearcă în câteva secunde.'); return; }
      const withQty = (items || []).filter(it => it.qty != null && it.qty !== '' && Number(it.qty) > 0);
      if (!withQty.length) { alert('Nu există produse cu cantitate de împachetat.'); return; }
      // Grupare pe phone_series_id, păstrând ordinea de apariție a grupurilor.
      const groups = new Map();
      withQty.forEach((it, i) => {
        const key = (it.phone_series_id != null) ? ('g' + it.phone_series_id) : ('solo' + i);
        if (!groups.has(key)) groups.set(key, { first: i, rows: [] });
        groups.get(key).rows.push(it);
      });
      const ordered = [...groups.values()].sort((a, b) => a.first - b.first);
      const aoa = [['Nr', 'Nume produs', 'Model telefon', 'EAN', 'PNK', 'Buc/cutie', 'Bucăți']];
      let n = 0;
      for (const g of ordered) {
        for (const it of g.rows) {
          n++;
          const upb = (it.units_per_box != null && it.units_per_box !== '') ? Number(it.units_per_box) : '';
          aoa.push([n, this.itemName(it), it.phone_label || '', String(it.ean || ''), it.pnk || '', upb, Number(it.qty)]);
        }
      }
      const ws = XLSX.utils.aoa_to_sheet(aoa);
      ws['!cols'] = [{ wch: 5 }, { wch: 50 }, { wch: 22 }, { wch: 18 }, { wch: 14 }, { wch: 10 }, { wch: 8 }];
      const wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws, 'Împachetare');
      const safe = (recNumber || '').toString().trim().replace(/[^\w.\-]+/g, '_');
      XLSX.writeFile(wb, 'impachetare' + (safe ? '-' + safe : '') + '.xlsx');
    },
    generatePacking() {
      this.buildPackingExcel(this.items, this.currentSession.reception_number);
    },
    downloadPacking(s) {
      this.buildPackingExcel(s.items || [], s.reception_number);
    },

    // ---- lista de sesiuni ----
    updateSessionInList(session) {
      if (!session) return;
      const i = this.sessions.findIndex(x => Number(x.id) === Number(session.id));
      if (i >= 0) this.sessions.splice(i, 1, session);
      else this.sessions.unshift(session);
    },
    async deleteSession(s) {
      if (!confirm('Ștergi sesiunea „' + s.name + '"?')) return;
      try {
        const fd = new FormData();
        fd.append('csrf_token', this.csrf);
        fd.append('id', s.id);
        const r = await fetch('<?= url('api/delete-reception.php') ?>', { method: 'POST', body: fd, credentials: 'same-origin' });
        const d = await r.json();
        if (!d.ok) throw new Error(d.error || 'Eroare');
        this.sessions = this.sessions.filter(x => x.id !== s.id);
      } catch (e) {
        alert('Nu am putut șterge sesiunea: ' + e.message);
      }
    },
    formatDate(s) {
      if (!s) return '';
      const d = new Date(s.replace(' ', 'T'));
      if (isNaN(d)) return s;
      return d.toLocaleDateString('ro-RO') + ' ' + d.toLocaleTimeString('ro-RO', { hour: '2-digit', minute: '2-digit' });
    }
  };
}
</script>

<?php require __DIR__ . '/includes/footer.php'; ?>
