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

$pageTitle  = 'Actualizare prețuri';
$breadcrumb = [['label' => 'Actualizare prețuri']];

$dbError = null;
$vatRate = vat_rate(); // cotă TVA (%) pentru afișarea prețului cu TVA

// Contul de lucru e cel global (selectat din header). 0 = toate conturile.
$activeId = active_account_id();

// ---- Filtre locale ----
$search       = trim((string)($_GET['q'] ?? ''));
$filterPrice  = $_GET['price'] ?? ''; // '', 'set' (preț nou setat), 'unset', 'changed' (diferit de curent)
$filterUnits  = $_GET['units'] ?? ''; // '', 'null', 'any', sau număr exact
$pageNum      = max(1, (int)($_GET['page'] ?? 1));
$allowedPer   = [50, 100, 200];
$perPage      = (int)($_GET['per_page'] ?? 50);
if (!in_array($perPage, $allowedPer, true)) $perPage = 50;

$products        = [];
$total           = 0;
$totalPages      = 1;
$eligibleCount   = 0;   // produse care POT fi împinse la eMAG pentru contul activ
$selectedAccount = null;
$unitsValues     = [];

try {
    if ($activeId > 0) {
        $rows = db_select("SELECT id, account_name, username FROM emag_accounts WHERE id = ? AND is_active = 1", [$activeId]);
        $selectedAccount = $rows[0] ?? null;
    }

    // Valori distincte de units_per_box pentru dropdown (în scopul contului activ)
    if ($activeId > 0) {
        $unitsValues = array_map('intval', array_column(
            db_select("SELECT DISTINCT units_per_box FROM products WHERE units_per_box IS NOT NULL AND emag_account_id = ? ORDER BY units_per_box ASC", [$activeId]),
            'units_per_box'
        ));
    } else {
        $unitsValues = array_map('intval', array_column(
            db_select("SELECT DISTINCT units_per_box FROM products WHERE units_per_box IS NOT NULL ORDER BY units_per_box ASC"),
            'units_per_box'
        ));
    }

    // WHERE comun: exclude produsele excluse (EAN sau categorie)
    $where  = [
        "(c.is_excluded IS NULL OR c.is_excluded = 0)",
        "(p.ean IS NULL OR p.ean NOT IN (SELECT ean FROM excluded_eans))",
    ];
    $params = [];

    if ($activeId > 0) {
        $where[] = 'p.emag_account_id = ?';
        $params[] = $activeId;
    }
    if ($search !== '') {
        $where[] = '(p.ean LIKE ? OR p.product_name LIKE ? OR p.pnk LIKE ? OR p.emag_id LIKE ?)';
        $q = '%' . $search . '%';
        array_push($params, $q, $q, $q, $q);
    }
    if ($filterPrice === 'set') {
        $where[] = '(p.sale_price IS NOT NULL AND p.sale_price > 0)';
    } elseif ($filterPrice === 'unset') {
        $where[] = '(p.sale_price IS NULL OR p.sale_price = 0)';
    } elseif ($filterPrice === 'changed') {
        $where[] = '(p.sale_price IS NOT NULL AND p.sale_price > 0 AND (p.current_sale_price IS NULL OR p.sale_price != p.current_sale_price))';
    } elseif ($filterPrice === 'out_of_range') {
        // Prețul verificat = cel nou (dacă e setat), altfel cel curent — la fel ca în UI.
        $where[] = "(COALESCE(NULLIF(p.sale_price, 0), p.current_sale_price) IS NOT NULL
                     AND ((p.min_sale_price IS NOT NULL AND COALESCE(NULLIF(p.sale_price, 0), p.current_sale_price) < p.min_sale_price)
                       OR (p.max_sale_price IS NOT NULL AND COALESCE(NULLIF(p.sale_price, 0), p.current_sale_price) > p.max_sale_price)))";
    } elseif ($filterPrice === 'no_range') {
        $where[] = '(p.min_sale_price IS NULL AND p.max_sale_price IS NULL)';
    }
    if ($filterUnits === 'null') {
        $where[] = 'p.units_per_box IS NULL';
    } elseif ($filterUnits === 'any') {
        $where[] = 'p.units_per_box IS NOT NULL';
    } elseif ($filterUnits !== '' && ctype_digit((string)$filterUnits)) {
        $where[] = 'p.units_per_box = ?';
        $params[] = (int)$filterUnits;
    }
    $whereSql = implode(' AND ', $where);

    $total = (int)db_scalar(
        "SELECT COUNT(*) FROM products p
         LEFT JOIN categories c ON c.id = p.category_id
         WHERE $whereSql",
        $params
    );
    $totalPages = max(1, (int)ceil($total / $perPage));
    if ($pageNum > $totalPages) $pageNum = $totalPages;
    $offset = ($pageNum - 1) * $perPage;

    $products = db_select(
        "SELECT p.id, p.product_name, p.ean, p.pnk, p.emag_id, p.emag_account_id,
                p.sale_price, p.current_sale_price, p.min_sale_price, p.max_sale_price,
                p.currency, p.price_synced_at,
                p.units_per_box,
                a.account_name
         FROM products p
         LEFT JOIN categories c ON c.id = p.category_id
         LEFT JOIN emag_accounts a ON a.id = p.emag_account_id
         WHERE $whereSql
         ORDER BY p.price_synced_at IS NOT NULL, p.product_name COLLATE NOCASE
         LIMIT ? OFFSET ?",
        array_merge($params, [$perPage, $offset])
    );

    // Câte produse pot fi efectiv împinse la eMAG pentru contul activ
    if ($activeId > 0) {
        $eligibleCount = (int)db_scalar(
            "SELECT COUNT(*) FROM products p
             LEFT JOIN categories c ON c.id = p.category_id
             WHERE p.emag_account_id = ?
               AND p.emag_id IS NOT NULL AND p.emag_id != ''
               AND p.sale_price IS NOT NULL AND p.sale_price > 0
               AND (c.is_excluded IS NULL OR c.is_excluded = 0)
               AND (p.ean IS NULL OR p.ean NOT IN (SELECT ean FROM excluded_eans))",
            [$activeId]
        );
    }
} catch (Throwable $ex) {
    $dbError = $ex->getMessage();
}

function price_url(array $overrides = []): string {
    $current = [
        'q'        => $_GET['q']        ?? null,
        'price'    => $_GET['price']    ?? null,
        'units'    => $_GET['units']    ?? null,
        'page'     => $_GET['page']     ?? null,
        'per_page' => $_GET['per_page'] ?? null,
    ];
    $merged = array_filter(array_merge($current, $overrides), fn($v) => $v !== null && $v !== '');
    return '?' . http_build_query($merged);
}

$startRow = $total > 0 ? (($pageNum - 1) * $perPage) + 1 : 0;
$endRow   = min($pageNum * $perPage, $total);

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

<?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="pricesPage({
       rows: <?= htmlspecialchars(json_encode($products), ENT_QUOTES, 'UTF-8') ?>,
       csrf: '<?= e(csrf_token()) ?>',
       accountId: <?= $activeId ?>,
       eligible: <?= $eligibleCount ?>,
       startIndex: <?= $startRow ?: 1 ?>,
       vatRate: <?= json_encode($vatRate) ?>
     })">

  <!-- Header -->
  <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">Actualizare prețuri</h1>
      <p class="text-sm text-slate-500 mt-0.5">
        Preț de vânzare (fără TVA). Trimis la eMAG prin <code>product_offer/save</code>.
        <span class="text-slate-400">Prețul curent e citit la sync-ul eMAG.</span>
      </p>
    </div>
  </div>

  <!-- Indicator cont activ -->
  <div class="mb-4 flex items-center gap-2 text-sm">
    <span class="text-slate-500">Cont de lucru:</span>
    <?php if ($selectedAccount): ?>
      <span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg bg-brand-50 text-brand-700 font-medium">
        <span class="w-1.5 h-1.5 rounded-full bg-brand-500"></span><?= e($selectedAccount['account_name']) ?>
      </span>
    <?php else: ?>
      <span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg bg-slate-100 text-slate-600 font-medium">Toate conturile</span>
    <?php endif; ?>
    <span class="text-slate-400">— schimbă din selectorul din header.</span>
  </div>

  <!-- Filtre -->
  <form method="get" data-ajax-filters class="bg-white border border-slate-100 rounded-xl shadow-soft p-4 mb-4">
    <div class="grid grid-cols-1 md:grid-cols-5 gap-3">
      <div class="md:col-span-2">
        <label class="block text-xs font-medium text-slate-700 mb-1">Caută</label>
        <input type="text" name="q" value="<?= e($search) ?>" placeholder="Nume, EAN, PNK, eMAG ID…"
          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">Preț nou</label>
        <select name="price" onchange="this.form.requestSubmit()"
          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 bg-white">
          <option value="">Toate</option>
          <option value="set"     <?= $filterPrice === 'set'     ? 'selected' : '' ?>>Cu preț nou setat</option>
          <option value="unset"   <?= $filterPrice === 'unset'   ? 'selected' : '' ?>>Fără preț nou</option>
          <option value="changed" <?= $filterPrice === 'changed' ? 'selected' : '' ?>>Modificat față de curent</option>
          <option disabled>──────────</option>
          <option value="out_of_range" <?= $filterPrice === 'out_of_range' ? 'selected' : '' ?>>În afara min/max</option>
          <option value="no_range"     <?= $filterPrice === 'no_range'     ? 'selected' : '' ?>>Fără interval min/max</option>
        </select>
      </div>
      <div>
        <label class="block text-xs font-medium text-slate-700 mb-1">Nr. bucăți</label>
        <select name="units" onchange="this.form.requestSubmit()"
          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 bg-white">
          <option value="">Toate</option>
          <option value="null" <?= $filterUnits === 'null' ? 'selected' : '' ?>>Fără valoare</option>
          <option value="any"  <?= $filterUnits === 'any'  ? 'selected' : '' ?>>Cu valoare (oricare)</option>
          <?php if ($unitsValues): ?>
            <option disabled>──────────</option>
            <?php foreach ($unitsValues as $val): ?>
              <option value="<?= (int)$val ?>" <?= (string)$filterUnits === (string)$val ? 'selected' : '' ?>>= <?= (int)$val ?> buc</option>
            <?php endforeach; ?>
          <?php endif; ?>
        </select>
      </div>
      <div>
        <label class="block text-xs font-medium text-slate-700 mb-1">Pe pagină</label>
        <select name="per_page" onchange="this.form.requestSubmit()"
          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 bg-white">
          <?php foreach ($allowedPer as $pp): ?>
            <option value="<?= $pp ?>" <?= $perPage === $pp ? 'selected' : '' ?>><?= $pp ?></option>
          <?php endforeach; ?>
        </select>
      </div>
    </div>
    <?php if ($search !== '' || $filterPrice !== '' || $filterUnits !== ''): ?>
      <div class="mt-3 flex items-center gap-3">
        <button type="submit" class="px-3 py-1.5 text-sm font-medium text-white bg-brand-600 hover:bg-brand-700 rounded-lg transition">Aplică</button>
        <a href="<?= e(url('prices.php')) ?>" class="text-sm text-slate-500 hover:text-slate-700">Resetează filtrele</a>
      </div>
    <?php endif; ?>
  </form>

  <!-- Panou Sync la eMAG -->
  <div class="bg-white border border-slate-100 rounded-xl shadow-soft p-5 mb-4">
    <div class="flex items-center justify-between gap-4 flex-wrap">
      <div class="text-sm">
        <?php if ($selectedAccount): ?>
          <div class="font-medium text-slate-800">Trimite prețurile la <span class="text-brand-700"><?= e($selectedAccount['account_name']) ?></span></div>
          <div class="text-slate-500 mt-0.5">
            <strong x-text="eligible"></strong> produse cu preț nou (&gt; 0) și <code>emag_id</code> sunt gata de trimis.
          </div>
        <?php else: ?>
          <div class="font-medium text-slate-800">Selectează un cont anume din header pentru a trimite prețurile la eMAG</div>
          <div class="text-slate-500 mt-0.5">Push-ul se face per cont (credențiale eMAG diferite).</div>
        <?php endif; ?>
      </div>
      <button @click="startSync()"
        :disabled="running || !accountId || eligible === 0"
        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 shadow-soft transition disabled:opacity-50 disabled:cursor-not-allowed">
        <svg x-show="!running" 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 4v5h.582M20 20v-5h-.581M5.5 9a7.5 7.5 0 0113 -2.5M18.5 15a7.5 7.5 0 01-13 2.5"/></svg>
        <span x-show="running" class="spinner"></span>
        <span x-text="running ? 'Trimit…' : 'Sync prețuri la eMAG'"></span>
      </button>
    </div>

    <!-- Progress -->
    <template x-if="running || done">
      <div class="mt-5">
        <div class="flex items-center justify-between text-sm mb-2">
          <div class="font-medium text-slate-700">
            <span x-show="running">Trimitere în progres…</span>
            <span x-show="done && !error" class="text-emerald-700">✓ Trimitere finalizată</span>
            <span x-show="error" class="text-rose-700">✗ Trimitere eșuată</span>
          </div>
          <div class="text-xs text-slate-500"><span x-text="totals.processed"></span> / <span x-text="totals.total"></span></div>
        </div>
        <div class="w-full h-2 bg-slate-100 rounded-full overflow-hidden">
          <div class="h-full bg-gradient-to-r from-brand-500 to-brand-600 transition-all duration-300" :style="`width: ${progressPercent()}%`"></div>
        </div>
        <div class="mt-4 grid grid-cols-3 gap-3">
          <div class="bg-emerald-50 rounded-lg p-3">
            <div class="text-[11px] uppercase tracking-wide text-emerald-700 font-medium">Trimise</div>
            <div class="text-xl font-bold text-emerald-900 mt-0.5" x-text="totals.sent"></div>
          </div>
          <div class="bg-rose-50 rounded-lg p-3">
            <div class="text-[11px] uppercase tracking-wide text-rose-700 font-medium">Erori</div>
            <div class="text-xl font-bold text-rose-900 mt-0.5" x-text="totals.failed"></div>
          </div>
          <div class="bg-slate-50 rounded-lg p-3">
            <div class="text-[11px] uppercase tracking-wide text-slate-600 font-medium">Procesate</div>
            <div class="text-xl font-bold text-slate-900 mt-0.5" x-text="totals.processed"></div>
          </div>
        </div>
        <div class="mt-4">
          <div class="bg-slate-900 text-slate-300 font-mono text-[12px] rounded-lg p-3 max-h-56 overflow-y-auto" x-ref="logBox">
            <template x-for="(line, i) in logLines" :key="i">
              <div class="leading-relaxed" :class="line.type === 'error' ? 'text-rose-400' : (line.type === 'success' ? 'text-emerald-400' : 'text-slate-400')">
                <span class="text-slate-600" x-text="line.time"></span><span x-text="line.text"></span>
              </div>
            </template>
            <template x-if="logLines.length === 0"><div class="text-slate-600 italic">Așteptare…</div></template>
          </div>
        </div>
        <template x-if="done">
          <div class="mt-3 text-sm">
            <a href="" @click.prevent="window.location.reload()" class="text-brand-600 hover:text-brand-700 font-medium">↻ Reîncarcă lista</a>
          </div>
        </template>
      </div>
    </template>
  </div>

  <!-- Bara setare în masă (apare când ai selecții) -->
  <div x-show="selectedIds.length > 0" x-cloak
       class="bg-brand-50 border border-brand-200 rounded-xl shadow-soft p-4 mb-4">
    <div class="flex items-center justify-between gap-3 mb-3">
      <div class="text-sm font-medium text-brand-900">
        <span x-text="selectedIds.length"></span> selectate — ce vrei să setezi?
      </div>
      <button @click="clearSelection()" class="text-sm text-slate-600 hover:text-slate-800 whitespace-nowrap">Deselectează</button>
    </div>

    <!-- Alegerea câmpului: preț de vânzare SAU interval min/max.
         Sunt operații diferite: prețul se salvează local, intervalul pleacă direct la eMAG. -->
    <div class="inline-flex rounded-lg border border-brand-200 bg-white p-0.5 mb-3">
      <button @click="bulkMode = 'price'" type="button"
        class="px-3 py-1.5 text-sm font-medium rounded-md transition"
        :class="bulkMode === 'price' ? 'bg-brand-600 text-white shadow-soft' : 'text-slate-600 hover:text-slate-800'">
        Preț de vânzare
      </button>
      <button @click="bulkMode = 'range'" type="button"
        class="px-3 py-1.5 text-sm font-medium rounded-md transition"
        :class="bulkMode === 'range' ? 'bg-brand-600 text-white shadow-soft' : 'text-slate-600 hover:text-slate-800'">
        Interval min / max
      </button>
    </div>

    <!-- Mod 1: preț de vânzare (salvare locală) -->
    <div x-show="bulkMode === 'price'" class="flex flex-col sm:flex-row sm:items-end gap-3">
      <div class="flex-1 grid grid-cols-2 gap-3 sm:max-w-md">
        <div>
          <label class="block text-[11px] font-medium text-slate-600 mb-1">Preț nou (fără TVA)</label>
          <input type="number" min="0" max="999999" step="0.01" x-model="bulkPrice" @input="bulkNetInput()"
            placeholder="ex: 49.90"
            class="w-full px-2 py-1.5 text-sm text-right tabular-nums border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-500">
        </div>
        <div>
          <label class="block text-[11px] font-medium text-slate-600 mb-1">Preț nou (cu TVA)</label>
          <input type="number" min="0" max="999999" step="0.01" x-model="bulkPriceVat" @input="bulkVatInput()"
            placeholder="ex: 59.88"
            class="w-full px-2 py-1.5 text-sm text-right tabular-nums bg-slate-50 border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-500">
        </div>
      </div>
      <button @click="applyBulk()" :disabled="bulkSaving"
        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 shadow-soft transition disabled:opacity-50 whitespace-nowrap">
        <span x-show="bulkSaving" class="spinner"></span>
        <span x-text="bulkSaving ? 'Aplic…' : 'Aplică la selectate'"></span>
      </button>
    </div>

    <!-- Mod 2: interval min/max (pleacă la eMAG per produs) -->
    <div x-show="bulkMode === 'range'" class="flex flex-col sm:flex-row sm:items-end gap-3">
      <div class="flex-1 grid grid-cols-2 gap-3 sm:max-w-md">
        <div>
          <label class="block text-[11px] font-medium text-slate-600 mb-1">Preț minim (fără TVA)</label>
          <input type="number" min="0" max="999999" step="0.01" x-model="bulkMin"
            placeholder="ex: 40.00"
            class="w-full px-2 py-1.5 text-sm text-right tabular-nums border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-500">
        </div>
        <div>
          <label class="block text-[11px] font-medium text-slate-600 mb-1">Preț maxim (fără TVA)</label>
          <input type="number" min="0" max="999999" step="0.01" x-model="bulkMax"
            placeholder="ex: 60.00"
            class="w-full px-2 py-1.5 text-sm text-right tabular-nums border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-500">
        </div>
      </div>
      <button @click="applyBulkRange()" :disabled="bulkSaving"
        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 shadow-soft transition disabled:opacity-50 whitespace-nowrap">
        <span x-show="bulkSaving" class="spinner"></span>
        <span x-text="bulkSaving ? bulkProgressText() : 'Trimite la eMAG'"></span>
      </button>
    </div>

    <p class="text-[11px] text-slate-500 mt-2" x-show="bulkMode === 'price'">
      Se salvează doar local — trimite la eMAG din panoul de sus sau cu butonul „Trimite" de pe rând.
    </p>
    <p class="text-[11px] text-amber-700 mt-2" x-show="bulkMode === 'range'">
      Atenție: intervalul se trimite direct la eMAG, câte un apel per produs. Produsele fără <code>emag_id</code> sunt sărite.
    </p>
    <template x-if="bulkErrors.length > 0">
      <div class="mt-3 bg-white border border-rose-200 rounded-lg p-3 max-h-40 overflow-y-auto">
        <div class="text-xs font-medium text-rose-800 mb-1"><span x-text="bulkErrors.length"></span> eșuate:</div>
        <template x-for="(m, i) in bulkErrors" :key="i">
          <div class="text-[11px] text-rose-700 leading-relaxed" x-text="m"></div>
        </template>
      </div>
    </template>
  </div>

  <!-- Tabel -->
  <div class="bg-white border border-slate-100 rounded-xl shadow-soft overflow-hidden">
    <div class="overflow-x-auto">
      <table class="w-full text-sm">
        <thead>
          <tr class="border-b border-slate-100 bg-slate-50/60 text-left text-xs font-medium text-slate-500 uppercase tracking-wide">
            <th class="px-3 py-3 w-10">
              <input type="checkbox" @change="toggleAll($event.target.checked)" :checked="allSelected()"
                class="rounded border-slate-300 text-brand-600 focus:ring-brand-500 cursor-pointer">
            </th>
            <th class="px-2 py-3 w-12 text-right">#</th>
            <th class="px-4 py-3">Produs</th>
            <th class="px-3 py-3 w-36 text-right">Preț curent<br><span class="normal-case text-[10px] text-slate-400">eMAG, fără / cu TVA (<?= e(rtrim(rtrim(number_format($vatRate, 2, '.', ''), '0'), '.')) ?>%)</span></th>
            <th class="px-3 py-3 w-48">Min / Max<br><span class="normal-case text-[10px] text-slate-400">interval eMAG, fără TVA — se trimite la modificare</span></th>
            <th class="px-3 py-3 w-36">Preț nou<br><span class="normal-case text-[10px] text-slate-400">fără / cu TVA</span></th>
            <th class="px-3 py-3 w-28">Stare</th>
            <th class="px-3 py-3 w-32 text-center">Acțiune</th>
          </tr>
        </thead>
        <tbody class="divide-y divide-slate-50">
          <template x-for="(p, idx) in rows" :key="p.id">
            <tr class="hover:bg-slate-50/50" :class="isSelected(p.id) ? 'bg-brand-50/40' : ''">
              <td class="px-3 py-2.5">
                <input type="checkbox" :value="p.id" :checked="isSelected(p.id)" @change="toggleOne(p.id, $event.target.checked)"
                  class="rounded border-slate-300 text-brand-600 focus:ring-brand-500 cursor-pointer">
              </td>
              <td class="px-2 py-2.5 text-right text-xs text-slate-400 tabular-nums" x-text="startIndex + idx"></td>
              <td class="px-4 py-2.5">
                <div class="font-medium text-slate-800 line-clamp-2" x-text="p.product_name"></div>
                <div class="text-[11px] text-slate-400 font-mono mt-0.5 flex flex-wrap gap-x-3">
                  <span x-show="p.ean">EAN: <span x-text="p.ean"></span></span>
                  <span x-show="p.account_name" x-text="p.account_name"></span>
                  <span x-show="p.units_per_box != null && p.units_per_box !== ''"><span x-text="p.units_per_box"></span> buc</span>
                  <span x-show="!p.emag_id" class="text-amber-600">fără emag_id</span>
                </div>
              </td>
              <td class="px-3 py-2.5 text-right tabular-nums">
                <template x-if="p.current_sale_price !== null && p.current_sale_price !== ''">
                  <div>
                    <div class="text-slate-700"><span x-text="fmt(p.current_sale_price)"></span> <span class="text-[11px] text-slate-400" x-text="p.currency || 'RON'"></span></div>
                    <div class="text-[11px] text-slate-400">cu TVA: <span class="text-slate-500" x-text="fmtVat(p.current_sale_price)"></span></div>
                  </div>
                </template>
                <template x-if="p.current_sale_price === null || p.current_sale_price === ''">
                  <span class="text-slate-300">—</span>
                </template>
              </td>
              <!-- Interval permis de eMAG (min_sale_price / max_sale_price).
                   Docs: orice sale_price în afara intervalului e RESPINS de API. -->
              <td class="px-3 py-2.5">
                <template x-if="p.emag_id">
                  <div class="space-y-1">
                    <div class="flex items-center gap-1">
                      <input type="number" min="0" max="999999" step="0.01"
                        x-model="p.min_sale_price"
                        @focus="snapRange(p)"
                        @change="saveRange(p)"
                        @keydown.enter.prevent="$event.target.blur()"
                        :disabled="isSavingRange(p.id)"
                        placeholder="min"
                        title="Preț minim acceptat de eMAG (fără TVA)"
                        class="w-20 px-1.5 py-1 text-xs text-right tabular-nums border rounded-md focus:outline-none focus:ring-2 focus:ring-brand-500 disabled:opacity-50"
                        :class="outOfRange(p) ? 'border-rose-300' : 'border-slate-200'">
                      <span class="text-slate-300 text-xs">–</span>
                      <input type="number" min="0" max="999999" step="0.01"
                        x-model="p.max_sale_price"
                        @focus="snapRange(p)"
                        @change="saveRange(p)"
                        @keydown.enter.prevent="$event.target.blur()"
                        :disabled="isSavingRange(p.id)"
                        placeholder="max"
                        title="Preț maxim acceptat de eMAG (fără TVA)"
                        class="w-20 px-1.5 py-1 text-xs text-right tabular-nums border rounded-md focus:outline-none focus:ring-2 focus:ring-brand-500 disabled:opacity-50"
                        :class="outOfRange(p) ? 'border-rose-300' : 'border-slate-200'">
                    </div>
                    <div class="text-[11px] text-right flex items-center justify-end gap-1.5">
                      <span x-show="isSavingRange(p.id)" class="spinner"></span>
                      <span :class="outOfRange(p) ? 'text-rose-600 font-medium' : 'text-slate-400'"
                            x-text="isSavingRange(p.id) ? 'Trimit la eMAG…' : rangeNote(p)"></span>
                    </div>
                  </div>
                </template>
                <template x-if="!p.emag_id">
                  <div class="text-right text-[11px] text-slate-300" title="Fără emag_id — intervalul nu poate fi modificat">—</div>
                </template>
              </td>
              <td class="px-3 py-2.5">
                <div class="space-y-1.5">
                  <div class="relative">
                    <input type="number" min="0" max="999999" step="0.01"
                      x-model="p.sale_price"
                      @focus="snapshot(p)"
                      @change="saveRow(p)"
                      @keydown.enter.prevent="$event.target.blur()"
                      placeholder="—"
                      :title="outOfRange(p) ? 'Preț în afara intervalului min/max — eMAG va respinge oferta' : 'Preț fără TVA'"
                      class="w-32 pl-2 pr-14 py-1.5 text-sm text-right tabular-nums border rounded-md focus:outline-none focus:ring-2 focus:ring-brand-500"
                      :class="outOfRange(p) ? 'border-rose-400 bg-rose-50' : (priceChanged(p) ? 'border-amber-300 bg-amber-50' : 'border-slate-200')">
                    <span class="absolute right-2 top-2 text-[10px] text-slate-400 pointer-events-none">fără TVA</span>
                  </div>
                  <div class="relative">
                    <input type="number" min="0" max="999999" step="0.01"
                      :value="vatInputVal(p)"
                      @focus="snapshot(p)"
                      @change="setFromVat(p, $event.target.value)"
                      @keydown.enter.prevent="$event.target.blur()"
                      placeholder="—"
                      title="Preț cu TVA — completează automat prețul fără TVA"
                      class="w-32 pl-2 pr-14 py-1.5 text-sm text-right tabular-nums bg-slate-50 border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-500">
                    <span class="absolute right-2 top-2 text-[10px] text-slate-400 pointer-events-none">cu TVA</span>
                  </div>
                </div>
              </td>
              <td class="px-3 py-2.5">
                <template x-if="hasPrice(p) && p.price_synced_at && !priceChanged(p)">
                  <span class="inline-flex items-center gap-1 text-xs text-emerald-700">
                    <span class="w-1.5 h-1.5 rounded-full bg-emerald-500"></span> trimis
                  </span>
                </template>
                <template x-if="hasPrice(p) && (!p.price_synced_at || priceChanged(p))">
                  <span class="inline-flex items-center gap-1 text-xs text-sky-700">
                    <span class="w-1.5 h-1.5 rounded-full bg-sky-500"></span> de trimis
                  </span>
                </template>
                <template x-if="!hasPrice(p)">
                  <span class="inline-flex items-center gap-1 text-xs text-slate-400">
                    <span class="w-1.5 h-1.5 rounded-full bg-slate-300"></span> fără preț
                  </span>
                </template>
              </td>
              <td class="px-3 py-2.5 text-center">
                <template x-if="hasPrice(p) && p.emag_id">
                  <button @click="sendOne(p)" :disabled="isSending(p.id)"
                    class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-brand-600 hover:bg-brand-700 rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed"
                    :title="p.price_synced_at ? 'Retrimite prețul la eMAG' : 'Trimite prețul la eMAG'">
                    <span x-show="isSending(p.id)" class="spinner"></span>
                    <svg x-show="!isSending(p.id)" class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 12h14M12 5l7 7-7 7"/></svg>
                    <span x-text="isSending(p.id) ? 'Trimit…' : (p.price_synced_at ? 'Retrimite' : 'Trimite')"></span>
                  </button>
                </template>
                <template x-if="!(hasPrice(p) && p.emag_id)">
                  <span class="text-xs text-slate-300">—</span>
                </template>
              </td>
            </tr>
          </template>
          <template x-if="rows.length === 0">
            <tr><td colspan="8" class="px-4 py-12 text-center text-sm text-slate-400">Niciun produs.</td></tr>
          </template>
        </tbody>
      </table>
    </div>
  </div>

  <!-- Paginare -->
  <?php if ($totalPages > 1): ?>
    <div class="mt-4 flex items-center justify-between text-sm">
      <div class="text-slate-500">Afișez <strong><?= $startRow ?>–<?= $endRow ?></strong> din <strong><?= number_format($total, 0, ',', '.') ?></strong></div>
      <div class="flex items-center gap-1">
        <?php if ($pageNum > 1): ?>
          <a href="<?= e(price_url(['page' => $pageNum - 1])) ?>" class="px-3 py-1.5 border border-slate-200 rounded-lg hover:bg-slate-50">‹ Anterior</a>
        <?php endif; ?>
        <span class="px-3 py-1.5 text-slate-500">Pagina <?= $pageNum ?> / <?= $totalPages ?></span>
        <?php if ($pageNum < $totalPages): ?>
          <a href="<?= e(price_url(['page' => $pageNum + 1])) ?>" class="px-3 py-1.5 border border-slate-200 rounded-lg hover:bg-slate-50">Următor ›</a>
        <?php endif; ?>
      </div>
    </div>
  <?php endif; ?>

</div>

<script>
function pricesPage(cfg) {
  return {
    rows: cfg.rows,
    csrf: cfg.csrf,
    accountId: cfg.accountId,
    eligible: cfg.eligible,
    startIndex: cfg.startIndex,
    vatRate: parseFloat(cfg.vatRate) || 0,
    _snap: {},

    // --- Selecție multiplă ---
    selectedIds: [],
    bulkMode: 'price',   // 'price' = preț de vânzare (local) | 'range' = min/max (direct la eMAG)
    bulkPrice: '',
    bulkPriceVat: '',
    bulkMin: '',
    bulkMax: '',
    bulkSaving: false,
    bulkDone: 0,
    bulkErrors: [],

    // Bara de masă: sincronizare fără TVA ↔ cu TVA (valoarea salvată e tot cea fără TVA).
    bulkNetInput() {
      const s = String(this.bulkPrice).replace(',', '.').trim();
      const n = parseFloat(s);
      this.bulkPriceVat = (s === '' || isNaN(n)) ? '' : (Math.round(n * (1 + this.vatRate / 100) * 100) / 100).toFixed(2);
    },
    bulkVatInput() {
      const s = String(this.bulkPriceVat).replace(',', '.').trim();
      const n = parseFloat(s);
      this.bulkPrice = (s === '' || isNaN(n)) ? '' : (Math.round(n / (1 + this.vatRate / 100) * 100) / 100).toFixed(2);
    },

    isSelected(id) { return this.selectedIds.includes(id); },
    toggleOne(id, on) {
      if (on) { if (!this.isSelected(id)) this.selectedIds.push(id); }
      else    { this.selectedIds = this.selectedIds.filter(x => x !== id); }
    },
    allSelected() { return this.rows.length > 0 && this.selectedIds.length === this.rows.length; },
    toggleAll(on) { this.selectedIds = on ? this.rows.map(p => p.id) : []; },
    clearSelection() {
      this.selectedIds = [];
      this.bulkPrice = ''; this.bulkPriceVat = '';
      this.bulkMin = '';   this.bulkMax = '';
      this.bulkErrors = []; this.bulkDone = 0;
    },
    bulkProgressText() { return `Trimit… ${this.bulkDone}/${this.selectedIds.length}`; },

    // --- Helpers preț ---
    fmt(v) {
      const n = parseFloat(v);
      if (isNaN(n)) return '—';
      return n.toLocaleString('ro-RO', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    },
    // Preț cu TVA, formatat. Întoarce '—' dacă valoarea de bază (fără TVA) lipsește.
    fmtVat(v) {
      const n = parseFloat(v);
      if (isNaN(n)) return '—';
      return (n * (1 + this.vatRate / 100)).toLocaleString('ro-RO', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    },
    // Valoarea pentru inputul „cu TVA" (string cu 2 zecimale), derivată din sale_price (fără TVA).
    vatInputVal(p) {
      if (p.sale_price === null || p.sale_price === '' || p.sale_price === undefined) return '';
      const n = parseFloat(p.sale_price);
      if (isNaN(n)) return '';
      return (n * (1 + this.vatRate / 100)).toFixed(2);
    },
    // Userul a introdus prețul CU TVA → calculez prețul fără TVA și salvez (valoarea stocată/trimisă la eMAG).
    setFromVat(p, val) {
      const s = String(val).replace(',', '.').trim();
      if (s === '') { p.sale_price = ''; this.saveRow(p); return; }
      const n = parseFloat(s);
      if (isNaN(n) || n < 0) return;
      const net = n / (1 + this.vatRate / 100);
      p.sale_price = (Math.round(net * 100) / 100).toFixed(2);
      this.saveRow(p);
    },
    hasPrice(p) {
      return p.sale_price !== null && p.sale_price !== '' && p.sale_price !== undefined && parseFloat(p.sale_price) > 0;
    },

    // --- Interval min/max impus de eMAG ---
    // Docs v4.5.1: min_sale_price / max_sale_price sunt obligatorii la primul save
    // al produsului, iar sale_price e validat față de ele — în afara intervalului,
    // oferta e respinsă. Le citim la sync, deci sunt read-only aici.
    num(v) {
      if (v === null || v === '' || v === undefined) return null;
      const n = parseFloat(v);
      return isNaN(n) ? null : n;
    },
    hasRange(p) { return this.num(p.min_sale_price) !== null || this.num(p.max_sale_price) !== null; },
    // Prețul relevant pentru verificare: cel nou (dacă e setat), altfel cel curent.
    checkPrice(p) { return this.hasPrice(p) ? parseFloat(p.sale_price) : this.num(p.current_sale_price); },
    outOfRange(p) {
      const v = this.checkPrice(p);
      if (v === null) return false;
      const lo = this.num(p.min_sale_price), hi = this.num(p.max_sale_price);
      return (lo !== null && v < lo) || (hi !== null && v > hi);
    },
    rangeNote(p) {
      const lo = this.num(p.min_sale_price), hi = this.num(p.max_sale_price);
      if (lo === null && hi === null) return 'fără interval';
      if (lo === null || hi === null)  return 'interval incomplet';
      if (hi <= lo) return '⚠ max ≤ min';
      const v = this.checkPrice(p);
      if (v === null) return 'fără preț de verificat';
      if (v < lo) return '⚠ sub minim';
      if (v > hi) return '⚠ peste maxim';
      return '✓ în interval';
    },

    // Editarea intervalului merge DIRECT la eMAG (docs: sale_price e validat față
    // de min/max, deci o valoare locală nesincronizată ar fi înșelătoare).
    // Scriem local doar după confirmarea API-ului; la eroare revenim la valorile vechi.
    _snapRange: {},
    savingRangeIds: [],
    isSavingRange(id) { return this.savingRangeIds.includes(id); },
    snapRange(p) {
      this._snapRange[p.id] = { min_sale_price: p.min_sale_price, max_sale_price: p.max_sale_price };
    },
    revertRange(p) {
      const s = this._snapRange[p.id];
      if (s) Object.assign(p, s);
    },
    async saveRange(p) {
      if (this.isSavingRange(p.id)) return;
      const lo = this.num(p.min_sale_price), hi = this.num(p.max_sale_price);
      // Ambele sunt obligatorii la eMAG — cât timp perechea e incompletă, așteptăm.
      if (lo === null || hi === null) return;
      if (lo <= 0 || hi <= 0) { alert('Minimul și maximul trebuie să fie mai mari decât 0.'); this.revertRange(p); return; }
      if (hi <= lo) { alert('Prețul maxim trebuie să fie mai mare decât cel minim.'); this.revertRange(p); return; }
      // Nimic de trimis dacă perechea e neschimbată față de valorile de la focus.
      const s = this._snapRange[p.id];
      if (s && this.num(s.min_sale_price) === lo && this.num(s.max_sale_price) === hi) return;

      this.savingRangeIds.push(p.id);
      try {
        const fd = new FormData();
        fd.append('csrf_token', this.csrf);
        fd.append('id', p.id);
        fd.append('min_sale_price', lo);
        fd.append('max_sale_price', hi);
        const r = await fetch('<?= url('api/save-price-range.php') ?>', { method: 'POST', body: fd });
        const data = await r.json();
        if (!data.ok) throw new Error(data.error || 'Eroare');
        if (data.product) Object.assign(p, data.product);
        this.snapRange(p);
      } catch (e) {
        this.revertRange(p);
        alert('Eroare la salvarea intervalului pentru „' + (p.product_name || '').slice(0, 60) + '": ' + e.message);
      } finally {
        this.savingRangeIds = this.savingRangeIds.filter(x => x !== p.id);
      }
    },
    priceChanged(p) {
      if (!this.hasPrice(p)) return false;
      const cur = (p.current_sale_price === null || p.current_sale_price === '' || p.current_sale_price === undefined)
        ? null : parseFloat(p.current_sale_price);
      return cur === null || parseFloat(p.sale_price) !== cur;
    },

    // --- Trimitere individuală la eMAG ---
    sendingIds: [],
    isSending(id) { return this.sendingIds.includes(id); },
    async sendOne(p) {
      if (this.isSending(p.id)) return;
      this.sendingIds.push(p.id);
      try {
        const fd = new FormData();
        fd.append('csrf_token', this.csrf);
        fd.append('id', p.id);
        const r = await fetch('<?= url('api/price-send-one.php') ?>', { method: 'POST', body: fd });
        const data = await r.json();
        if (!data.ok) throw new Error(data.error || 'Eroare');
        if (data.product) Object.assign(p, data.product);
      } catch (e) {
        alert('Eroare trimitere „' + (p.product_name || '').slice(0, 60) + '": ' + e.message);
      } finally {
        this.sendingIds = this.sendingIds.filter(x => x !== p.id);
      }
    },

    async applyBulk() {
      if (this.selectedIds.length === 0 || this.bulkSaving) return;
      if (String(this.bulkPrice).trim() === '') { alert('Completează prețul nou.'); return; }
      const val = parseFloat(String(this.bulkPrice).replace(',', '.'));
      if (isNaN(val) || val < 0) { alert('Preț invalid.'); return; }
      this.bulkSaving = true;
      try {
        // Salvez secvențial fiecare produs selectat (endpoint per-produs).
        for (const id of this.selectedIds) {
          const fd = new FormData();
          fd.append('csrf_token', this.csrf);
          fd.append('id', id);
          fd.append('sale_price', val);
          const r = await fetch('<?= url('api/save-price.php') ?>', { method: 'POST', body: fd });
          const data = await r.json();
          if (data.ok && data.product) {
            const row = this.rows.find(x => x.id == id);
            if (row) Object.assign(row, data.product);
          }
        }
        this.bulkPrice = '';
        this.bulkPriceVat = '';
      } catch (e) {
        alert('Eroare salvare în masă: ' + e.message);
      } finally {
        this.bulkSaving = false;
      }
    },

    // Aplicare în masă a intervalului min/max. Spre deosebire de preț, fiecare
    // produs înseamnă un apel la eMAG — deci confirmăm întâi, throttle-uim între
    // apeluri (~2.5 req/s, sub limita eMAG de 3/s) și raportăm eșecurile.
    async applyBulkRange() {
      if (this.selectedIds.length === 0 || this.bulkSaving) return;
      const lo = this.num(this.bulkMin), hi = this.num(this.bulkMax);
      if (lo === null || hi === null) { alert('Completează și minimul, și maximul.'); return; }
      if (lo <= 0 || hi <= 0) { alert('Valorile trebuie să fie mai mari decât 0.'); return; }
      if (hi <= lo) { alert('Prețul maxim trebuie să fie mai mare decât cel minim.'); return; }

      const targets = this.rows.filter(p => this.isSelected(p.id) && p.emag_id);
      const skipped = this.selectedIds.length - targets.length;
      if (targets.length === 0) { alert('Niciun produs selectat nu are emag_id.'); return; }
      if (!confirm(
        `Trimit intervalul ${lo} – ${hi} (fără TVA) la eMAG pentru ${targets.length} produse` +
        (skipped > 0 ? ` (${skipped} sărite, fără emag_id)` : '') + '.\n\nContinui?'
      )) return;

      this.bulkSaving = true;
      this.bulkDone = 0;
      this.bulkErrors = [];
      try {
        for (const p of targets) {
          try {
            const fd = new FormData();
            fd.append('csrf_token', this.csrf);
            fd.append('id', p.id);
            fd.append('min_sale_price', lo);
            fd.append('max_sale_price', hi);
            const r = await fetch('<?= url('api/save-price-range.php') ?>', { method: 'POST', body: fd });
            const data = await r.json();
            if (!data.ok) throw new Error(data.error || 'Eroare');
            if (data.product) Object.assign(p, data.product);
          } catch (e) {
            this.bulkErrors.push((p.product_name || ('#' + p.id)).slice(0, 60) + ': ' + e.message);
          }
          this.bulkDone++;
          await new Promise(res => setTimeout(res, 400)); // throttle eMAG
        }
        if (this.bulkErrors.length === 0) { this.bulkMin = ''; this.bulkMax = ''; }
      } finally {
        this.bulkSaving = false;
      }
    },

    running: false,
    done: false,
    error: false,
    totals: { sent: 0, failed: 0, processed: 0, total: 0 },
    logLines: [],

    snapshot(p) { this._snap[p.id] = { sale_price: p.sale_price }; },

    async saveRow(p) {
      try {
        const fd = new FormData();
        fd.append('csrf_token', this.csrf);
        fd.append('id', p.id);
        fd.append('sale_price', p.sale_price ?? '');
        const r = await fetch('<?= url('api/save-price.php') ?>', { method: 'POST', body: fd });
        const data = await r.json();
        if (!data.ok) throw new Error(data.error || 'Eroare');
        Object.assign(p, data.product); // include price_synced_at = null
      } catch (e) {
        const s = this._snap[p.id];
        if (s) Object.assign(p, s);
        alert('Eroare salvare: ' + e.message);
      }
    },

    progressPercent() {
      if (this.done) return 100;
      if (this.totals.total > 0) return Math.min(99, Math.round((this.totals.processed / this.totals.total) * 100));
      return 5;
    },

    log(text, type = 'info') {
      const t = new Date().toLocaleTimeString('ro-RO');
      this.logLines.push({ time: `[${t}] `, text, type });
      this.$nextTick(() => { if (this.$refs.logBox) this.$refs.logBox.scrollTop = this.$refs.logBox.scrollHeight; });
    },

    async startSync() {
      if (!this.accountId || this.eligible === 0 || this.running) return;
      this.running = true; this.done = false; this.error = false;
      this.totals = { sent: 0, failed: 0, processed: 0, total: this.eligible };
      this.logLines = [];
      this.log(`Start trimitere prețuri (${this.eligible} produse)`, 'info');

      let offset = 0;
      let safety = 1000;
      try {
        while (safety-- > 0) {
          const fd = new FormData();
          fd.append('csrf_token', this.csrf);
          fd.append('account_id', this.accountId);
          fd.append('offset', offset);
          const r = await fetch('<?= url('api/price-sync.php') ?>', { method: 'POST', body: fd });
          const data = await r.json();
          if (!data.ok) throw new Error(data.error || 'Eroare necunoscută');

          this.totals.total      = data.total;
          this.totals.sent      += data.stats.sent;
          this.totals.failed    += data.stats.failed;
          this.totals.processed += data.processed;
          this.log(`  ✓ lot: ${data.processed} procesate · ${data.stats.sent} trimise · ${data.stats.failed} erori`, 'success');
          (data.errors_log || []).forEach(m => this.log(`  ⚠ ${m}`, 'error'));

          if (!data.has_more || data.processed === 0) break;
          offset = data.next_offset;
        }
        this.log(`✓ FINALIZAT: ${this.totals.sent} trimise, ${this.totals.failed} erori`, 'success');
        this.done = true;
      } catch (e) {
        this.log(`✗ EROARE: ${e.message}`, 'error');
        this.error = true; this.done = true;
      } finally {
        this.running = false;
      }
    }
  };
}
</script>

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