<?php
// panel_home_publis.php (PHP 8.2) - 1 solo archivo
// 1) Muestra notas como “home”
// 2) Entre cada nota: bloque “Poner publi” (slot/lugar)
// 3) Click -> modal con publis
// 4) Elegís una publi -> se le asigna el valor de ese lugar (ej 100000001)

declare(strict_types=1);

error_reporting(E_ALL);
ini_set('display_errors', '1');

session_start();

require_once __DIR__ . '/concha.php';
if (is_file(__DIR__ . '/url_amigable.php')) {
    require_once __DIR__ . '/url_amigable.php';
}

// -------------------- CONFIG --------------------
$START_LUGAR = 100000001;  // primer slot (ej: 100000001). Se incrementa +1 por cada “entre-nota”.
$NOTAS_LIMIT = 30;         // cuántas notas mostrar en el panel (para no cargar infinito)

// Login simple (opcional) - cambiá si querés
$ADMIN_USER = 'admin';
$ADMIN_PASS = 'netfan';

// ------------------------------------------------
function e(string $s): string {
    return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

function base_url(): string {
    if (isset($GLOBALS['dom']) && is_string($GLOBALS['dom']) && $GLOBALS['dom'] !== '') {
        return rtrim($GLOBALS['dom'], '/');
    }
    $https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
    $proto = $https ? 'https' : 'http';
    $host  = $_SERVER['HTTP_HOST'] ?? 'localhost';
    return $proto . '://' . $host;
}

function db(): mysqli {
    if (isset($GLOBALS['conn']) && $GLOBALS['conn'] instanceof mysqli) {
        $GLOBALS['conn']->set_charset('utf8mb4');
        return $GLOBALS['conn'];
    }
    if (isset($GLOBALS['con']) && $GLOBALS['con'] instanceof mysqli) {
        $GLOBALS['con']->set_charset('utf8mb4');
        return $GLOBALS['con'];
    }

    $host     = $GLOBALS['host']     ?? null;
    $usuario  = $GLOBALS['usuario']  ?? null;
    $contra   = $GLOBALS['contra']   ?? null;
    $basedatos= $GLOBALS['basedatos']?? null;

    if (!is_string($host) || !is_string($usuario) || !is_string($contra) || !is_string($basedatos)) {
        http_response_code(500);
        exit('Error: concha.php debe definir $conn (mysqli) o $con (mysqli) o $host/$usuario/$contra/$basedatos.');
    }

    $m = new mysqli($host, $usuario, $contra, $basedatos);
    if ($m->connect_error) {
        http_response_code(500);
        exit('Error DB: ' . $m->connect_error);
    }
    $m->set_charset('utf8mb4');
    $GLOBALS['conn'] = $m;
    return $m;
}

function slug(string $titulo): string {
    if (function_exists('urls_amigables')) return (string)urls_amigables($titulo);
    $s = mb_strtolower(trim($titulo), 'UTF-8');
    $s = preg_replace('~[^\pL\pN]+~u', '-', $s) ?? $s;
    return trim($s, '-');
}

function csrf_token(): string {
    if (!isset($_SESSION['csrf']) || !is_string($_SESSION['csrf']) || $_SESSION['csrf'] === '') {
        $_SESSION['csrf'] = bin2hex(random_bytes(16));
    }
    return (string)$_SESSION['csrf'];
}

function csrf_check(string $t): bool {
    return isset($_SESSION['csrf']) && is_string($_SESSION['csrf']) && hash_equals((string)$_SESSION['csrf'], $t);
}

// -------------------- LOGIN --------------------
if (isset($_GET['logout'])) {
    unset($_SESSION['home_publis_ok']);
    header('Location: ' . basename(__FILE__));
    exit;
}

if (!isset($_SESSION['home_publis_ok']) || $_SESSION['home_publis_ok'] !== true) {
    $err = '';
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['login'])) {
        $u = (string)($_POST['user'] ?? '');
        $p = (string)($_POST['pass'] ?? '');
        if (hash_equals($ADMIN_USER, $u) && hash_equals($ADMIN_PASS, $p)) {
            $_SESSION['home_publis_ok'] = true;
            csrf_token();
            header('Location: ' . basename(__FILE__));
            exit;
        }
        $err = 'Login incorrecto.';
    }
    ?>
    <!doctype html>
    <html lang="es">
    <head>
      <meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">
      <title>Panel Home + Publis</title>
    </head>
    <body class="bg-light">
      <div class="container" style="max-width:420px;padding-top:40px;">
        <div class="card">
          <div class="card-body">
            <h1 class="h5 mb-3">Panel Home + Publis</h1>
            <?php if ($err): ?><div class="alert alert-danger"><?= e($err) ?></div><?php endif; ?>
            <form method="post">
              <input type="hidden" name="login" value="1">
              <div class="form-group">
                <label>Usuario</label>
                <input class="form-control" name="user" required>
              </div>
              <div class="form-group">
                <label>Clave</label>
                <input class="form-control" type="password" name="pass" required>
              </div>
              <button class="btn btn-primary btn-block">Entrar</button>
            </form>
          </div>
        </div>
      </div>
    </body>
    </html>
    <?php
    exit;
}

// -------------------- AJAX ENDPOINTS --------------------
$conn = db();
$dom  = base_url();

function json_out(array $data, int $code = 200): void {
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data);
    exit;
}

function fetch_ads(mysqli $conn, string $dom, string $q = ''): array {
    // Lista unificada (JPG + GIF/PNG/WEBP). No filtramos por lugar (para que puedas reasignar).
    $items = [];

    $qLike = '%' . $q . '%';

    // JPG (tabla publicidades: img sin extensión)
    if ($q !== '') {
        $stmt = $conn->prepare("SELECT id,img,url,carpetafoto,lugar FROM publicidades WHERE img LIKE ? OR url LIKE ? ORDER BY id DESC LIMIT 200");
        if ($stmt) {
            $stmt->bind_param("ss", $qLike, $qLike);
            $stmt->execute();
            $r = $stmt->get_result();
            while ($p = $r->fetch_assoc()) {
                $carp = (string)($p['carpetafoto'] ?? 'publicidades_uploads');
                $img  = (string)$p['img'];
                $src1 = $dom . '/' . ltrim($carp, '/') . '/resize_' . $img . '.jpg';
                $src2 = $dom . '/' . ltrim($carp, '/') . '/' . $img . '.jpg';
                $items[] = [
                    'tipo' => 'jpg',
                    'id'   => (int)$p['id'],
                    'img'  => $img,
                    'url'  => (string)($p['url'] ?? ''),
                    'lugar'=> (int)($p['lugar'] ?? 0),
                    'src'  => $src1,
                    'src_fallback' => $src2,
                ];
            }
            $r->free();
            $stmt->close();
        }
    } else {
        $r = $conn->query("SELECT id,img,url,carpetafoto,lugar FROM publicidades ORDER BY id DESC LIMIT 200");
        if ($r) {
            while ($p = $r->fetch_assoc()) {
                $carp = (string)($p['carpetafoto'] ?? 'publicidades_uploads');
                $img  = (string)$p['img'];
                $src1 = $dom . '/' . ltrim($carp, '/') . '/resize_' . $img . '.jpg';
                $src2 = $dom . '/' . ltrim($carp, '/') . '/' . $img . '.jpg';
                $items[] = [
                    'tipo' => 'jpg',
                    'id'   => (int)$p['id'],
                    'img'  => $img,
                    'url'  => (string)($p['url'] ?? ''),
                    'lugar'=> (int)($p['lugar'] ?? 0),
                    'src'  => $src1,
                    'src_fallback' => $src2,
                ];
            }
            $r->free();
        }
    }

    // GIF/PNG/WEBP (tabla publicidades_gif: img con extensión)
    if ($q !== '') {
        $stmt = $conn->prepare("SELECT id,img,url,carpetafoto,lugar FROM publicidades_gif WHERE img LIKE ? OR url LIKE ? ORDER BY id DESC LIMIT 200");
        if ($stmt) {
            $stmt->bind_param("ss", $qLike, $qLike);
            $stmt->execute();
            $r = $stmt->get_result();
            while ($p = $r->fetch_assoc()) {
                $carp = (string)($p['carpetafoto'] ?? 'publicidades_uploads');
                $img  = (string)$p['img'];
                $src  = $dom . '/' . ltrim($carp, '/') . '/' . $img;
                $items[] = [
                    'tipo' => 'gifpng',
                    'id'   => (int)$p['id'],
                    'img'  => $img,
                    'url'  => (string)($p['url'] ?? ''),
                    'lugar'=> (int)($p['lugar'] ?? 0),
                    'src'  => $src,
                    'src_fallback' => '',
                ];
            }
            $r->free();
            $stmt->close();
        }
    } else {
        $r = $conn->query("SELECT id,img,url,carpetafoto,lugar FROM publicidades_gif ORDER BY id DESC LIMIT 200");
        if ($r) {
            while ($p = $r->fetch_assoc()) {
                $carp = (string)($p['carpetafoto'] ?? 'publicidades_uploads');
                $img  = (string)$p['img'];
                $src  = $dom . '/' . ltrim($carp, '/') . '/' . $img;
                $items[] = [
                    'tipo' => 'gifpng',
                    'id'   => (int)$p['id'],
                    'img'  => $img,
                    'url'  => (string)($p['url'] ?? ''),
                    'lugar'=> (int)($p['lugar'] ?? 0),
                    'src'  => $src,
                    'src_fallback' => '',
                ];
            }
            $r->free();
        }
    }

    return $items;
}

function slot_ad_map(mysqli $conn, int $startLugar, int $count, string $dom): array {
    // Devuelve map[lugar] = ad (1 solo por lugar, el de mayor id).
    $min = $startLugar;
    $max = $startLugar + max(0, $count - 1);

    $map = [];

    // JPG
    $stmt = $conn->prepare("SELECT id,img,url,carpetafoto,lugar FROM publicidades WHERE lugar BETWEEN ? AND ? ORDER BY lugar ASC, id DESC");
    if ($stmt) {
        $stmt->bind_param("ii", $min, $max);
        $stmt->execute();
        $r = $stmt->get_result();
        while ($p = $r->fetch_assoc()) {
            $l = (int)$p['lugar'];
            if (isset($map[$l])) continue;
            $carp = (string)($p['carpetafoto'] ?? 'publicidades_uploads');
            $img  = (string)$p['img'];
            $map[$l] = [
                'tipo' => 'jpg',
                'id'   => (int)$p['id'],
                'url'  => (string)($p['url'] ?? ''),
                'src'  => $dom . '/' . ltrim($carp, '/') . '/resize_' . $img . '.jpg',
                'src_fallback' => $dom . '/' . ltrim($carp, '/') . '/' . $img . '.jpg',
            ];
        }
        $r->free();
        $stmt->close();
    }

    // GIF/PNG
    $stmt = $conn->prepare("SELECT id,img,url,carpetafoto,lugar FROM publicidades_gif WHERE lugar BETWEEN ? AND ? ORDER BY lugar ASC, id DESC");
    if ($stmt) {
        $stmt->bind_param("ii", $min, $max);
        $stmt->execute();
        $r = $stmt->get_result();
        while ($p = $r->fetch_assoc()) {
            $l = (int)$p['lugar'];
            if (isset($map[$l])) continue;
            $carp = (string)($p['carpetafoto'] ?? 'publicidades_uploads');
            $img  = (string)$p['img'];
            $map[$l] = [
                'tipo' => 'gifpng',
                'id'   => (int)$p['id'],
                'url'  => (string)($p['url'] ?? ''),
                'src'  => $dom . '/' . ltrim($carp, '/') . '/' . $img,
                'src_fallback' => '',
            ];
        }
        $r->free();
        $stmt->close();
    }

    return $map;
}

function render_slot_preview(int $lugar, ?array $ad): string {
    $html = '<div class="slotbox" data-lugar="' . (int)$lugar . '">';
    $html .= '<div class="d-flex justify-content-between align-items-center">';
    $html .= '<div class="small text-muted">Lugar: <b>' . (int)$lugar . '</b></div>';
    $html .= '<div>';
    $html .= '<button type="button" class="btn btn-sm btn-primary btnPick" data-lugar="' . (int)$lugar . '">Poner publi</button> ';
    $html .= '<button type="button" class="btn btn-sm btn-outline-danger btnClear" data-lugar="' . (int)$lugar . '">Quitar</button>';
    $html .= '</div></div>';

    if ($ad) {
        $src = (string)($ad['src'] ?? '');
        $fallback = (string)($ad['src_fallback'] ?? '');
        $url = (string)($ad['url'] ?? '');
        $tipo = (string)($ad['tipo'] ?? '');
        $id = (int)($ad['id'] ?? 0);

        $html .= '<div class="mt-2 p-2 bg-white border">';
        $html .= '<div class="small text-muted mb-2">Asignada: <b>' . e($tipo) . '</b> · ID: <b>' . (int)$id . '</b></div>';
        if ($url !== '') {
            $html .= '<div class="small mb-2"><a href="' . e($url) . '" target="_blank" rel="noopener">' . e($url) . '</a></div>';
        }
        if ($src !== '') {
            if ($fallback !== '') {
                $html .= '<img class="img-fluid slotimg" src="' . e($src) . '" onerror="this.onerror=null;this.src=\'' . e($fallback) . '\';" alt="publi">';
            } else {
                $html .= '<img class="img-fluid slotimg" src="' . e($src) . '" alt="publi">';
            }
        }
        $html .= '</div>';
    } else {
        $html .= '<div class="mt-2 p-3 text-center text-muted border bg-white">Sin publi en este lugar</div>';
    }

    $html .= '</div>';
    return $html;
}

// AJAX router
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax'])) {
    $ajax = (string)$_POST['ajax'];
    $csrf = (string)($_POST['csrf'] ?? '');
    if (!csrf_check($csrf)) json_out(['ok' => false, 'err' => 'CSRF inválido'], 403);

    if ($ajax === 'list_ads') {
        $q = trim((string)($_POST['q'] ?? ''));
        $items = fetch_ads($conn, $dom, $q);
        json_out(['ok' => true, 'items' => $items]);
    }

    if ($ajax === 'assign_ad') {
        $tipo  = (string)($_POST['tipo'] ?? '');
        $idAd  = (int)($_POST['id'] ?? 0);
        $lugar = (int)($_POST['lugar'] ?? 0);

        if ($lugar <= 0 || $idAd <= 0 || ($tipo !== 'jpg' && $tipo !== 'gifpng')) {
            json_out(['ok' => false, 'err' => 'Parámetros inválidos'], 400);
        }

        // 1) limpiar cualquier publi que YA esté en ese lugar (en ambas tablas)
        $stmt = $conn->prepare("UPDATE publicidades SET lugar = 0 WHERE lugar = ?");
        if ($stmt) { $stmt->bind_param("i", $lugar); $stmt->execute(); $stmt->close(); }

        $stmt = $conn->prepare("UPDATE publicidades_gif SET lugar = 0 WHERE lugar = ?");
        if ($stmt) { $stmt->bind_param("i", $lugar); $stmt->execute(); $stmt->close(); }

        // 2) asignar esta publi al lugar
        if ($tipo === 'jpg') {
            $stmt = $conn->prepare("UPDATE publicidades SET lugar = ? WHERE id = ?");
        } else {
            $stmt = $conn->prepare("UPDATE publicidades_gif SET lugar = ? WHERE id = ?");
        }
        if (!$stmt) json_out(['ok' => false, 'err' => 'DB error: ' . $conn->error], 500);
        $stmt->bind_param("ii", $lugar, $idAd);
        $stmt->execute();
        $stmt->close();

        // 3) devolver preview actualizado
        $map = slot_ad_map($conn, $lugar, 1, $dom);
        $ad  = $map[$lugar] ?? null;
        $html = render_slot_preview($lugar, $ad);

        json_out(['ok' => true, 'html' => $html]);
    }

    if ($ajax === 'clear_slot') {
        $lugar = (int)($_POST['lugar'] ?? 0);
        if ($lugar <= 0) json_out(['ok' => false, 'err' => 'Lugar inválido'], 400);

        $stmt = $conn->prepare("UPDATE publicidades SET lugar = 0 WHERE lugar = ?");
        if ($stmt) { $stmt->bind_param("i", $lugar); $stmt->execute(); $stmt->close(); }

        $stmt = $conn->prepare("UPDATE publicidades_gif SET lugar = 0 WHERE lugar = ?");
        if ($stmt) { $stmt->bind_param("i", $lugar); $stmt->execute(); $stmt->close(); }

        $html = render_slot_preview($lugar, null);
        json_out(['ok' => true, 'html' => $html]);
    }

    json_out(['ok' => false, 'err' => 'Acción inválida'], 400);
}

// -------------------- PAGE DATA --------------------
$csrf = csrf_token();

// Notas (home-like)
$sqlNotas = "
    SELECT
      n.ID, n.titulo, n.bajada, n.d, n.m, n.a,
      n.carpetafoto, n.foto, n.ext_img,
      n.destacado, n.home
    FROM notas n
    WHERE n.ver = 'si' AND (n.home IS NULL OR n.home <> 'no')
    ORDER BY (n.destacado='si') DESC, n.ID DESC
    LIMIT ?
";
$stmt = $conn->prepare($sqlNotas);
if (!$stmt) { http_response_code(500); exit('Error prepare notas: ' . $conn->error); }
$stmt->bind_param("i", $NOTAS_LIMIT);
$stmt->execute();
$rs = $stmt->get_result();

$notas = [];
while ($row = $rs->fetch_assoc()) {
    $notas[] = $row;
}
$rs->free();
$stmt->close();

$slotsCount = count($notas); // 1 slot “entre-nota” por cada nota (abajo de cada nota)
$slotMap = slot_ad_map($conn, $START_LUGAR, $slotsCount, $dom);

?>
<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>Home + Publis (Panel)</title>

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

  <style>
    body { background:#f3f4f6; }
    .wrap { max-width: 980px; }
    .card-title a { color:#111; text-decoration:none; }
    .card-title a:hover { text-decoration:underline; }
    .thumb { width:100%; height:260px; object-fit:cover; background:#e9ecef; }
    .slotbox { margin:12px 0 24px 0; padding:12px; border:1px dashed #cbd5e1; background:#f8fafc; }
    .slotimg { max-height:260px; object-fit:contain; width:100%; background:#fff; }
    .adItem { cursor:pointer; border:1px solid #e5e7eb; background:#fff; padding:10px; border-radius:4px; }
    .adItem:hover { border-color:#3b82f6; }
    .adThumb { width:100%; height:160px; object-fit:contain; background:#fff; border:1px solid #eee; }
    .muted { color:#6b7280; }
  </style>
</head>

<body>
  <div class="container wrap py-4">
    <div class="d-flex justify-content-between align-items-center mb-3">
      <div>
        <h1 class="h5 mb-1">Home (preview) + Asignación de Publis</h1>
        <div class="small muted">Slots desde <b><?= (int)$START_LUGAR ?></b> · Notas mostradas: <b><?= (int)count($notas) ?></b></div>
      </div>
      <div>
        <a class="btn btn-outline-danger btn-sm" href="?logout=1">Salir</a>
      </div>
    </div>

    <?php if (!$notas): ?>
      <div class="alert alert-warning">No hay notas para mostrar (ver='si').</div>
    <?php else: ?>

      <div class="row">
        <?php
          $idx = 0;
          foreach ($notas as $n):
            $idx++;
            $ID = (int)$n['ID'];
            $titulo = (string)$n['titulo'];
            $bajada = (string)($n['bajada'] ?? '');
            $dest = ((string)($n['destacado'] ?? '') === 'si');

            $d = (string)($n['d'] ?? '');
            $m = (string)($n['m'] ?? '');
            $a = (string)($n['a'] ?? '');
            $fecha = trim($d . '/' . $m . '/' . $a, '/');

            $carpetafoto = (string)($n['carpetafoto'] ?? '');
            $foto = $n['foto'];
            $ext  = (string)($n['ext_img'] ?? '');

            $urlNota = $dom . '/nota/' . $ID . '/' . slug($titulo);

            $imgSrc = '';
            if (!empty($foto)) {
                $fotoStr = (string)$foto;
                if (stripos($fotoStr, 'http') === 0) {
                    $imgSrc = $fotoStr;
                } else {
                    // tu convención típica: /carpeta/thumbnail_{foto}{ext}
                    $imgSrc = $dom . '/' . ltrim($carpetafoto, '/') . '/thumbnail_' . $fotoStr . $ext;
                }
            }

            // lugar/slot para este “entre-nota”
            $lugar = $START_LUGAR + ($idx - 1);
            $ad = $slotMap[$lugar] ?? null;
        ?>
          <div class="col-12 col-md-6 mb-3">
            <div class="card <?= $dest ? 'border-primary' : '' ?>">
              <?php if ($imgSrc !== ''): ?>
                <a href="<?= e($urlNota) ?>" target="_blank" rel="noopener">
                  <img class="thumb" src="<?= e($imgSrc) ?>" alt="<?= e($titulo) ?>" loading="lazy">
                </a>
              <?php endif; ?>

              <div class="card-body">
                <?php if ($dest): ?>
                  <span class="badge badge-primary mb-2">Destacada</span>
                <?php endif; ?>

                <h2 class="h6 card-title m-0">
                  <a href="<?= e($urlNota) ?>" target="_blank" rel="noopener"><?= e($titulo) ?></a>
                </h2>

                <?php if ($fecha !== ''): ?>
                  <div class="small muted mt-1"><?= e($fecha) ?></div>
                <?php endif; ?>

                <?php if ($bajada !== ''): ?>
                  <p class="card-text mt-2 mb-0"><?= e($bajada) ?></p>
                <?php endif; ?>
              </div>
            </div>

            <!-- ENTRE CADA NOTA: SLOT -->
            <div id="slot-<?= (int)$lugar ?>">
              <?= render_slot_preview($lugar, $ad) ?>
            </div>
          </div>
        <?php endforeach; ?>
      </div>
    <?php endif; ?>
  </div>

  <!-- MODAL: LISTA DE PUBLIS -->
  <div class="modal fade" id="modalAds" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document" style="max-width:980px;">
      <div class="modal-content">
        <div class="modal-header">
          <div>
            <h5 class="modal-title mb-0">Elegir publi</h5>
            <div class="small muted" id="modalLugarText"></div>
          </div>
          <button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>

        <div class="modal-body">
          <div class="form-row align-items-center mb-3">
            <div class="col-md-8">
              <input id="qAds" class="form-control" placeholder="Buscar (img o url)...">
            </div>
            <div class="col-md-4 text-right">
              <button id="btnReloadAds" class="btn btn-outline-secondary">Buscar</button>
            </div>
          </div>

          <div id="adsGrid" class="row"></div>

          <div id="adsEmpty" class="text-center muted py-4" style="display:none;">
            No hay publis para mostrar.
          </div>
        </div>

        <div class="modal-footer">
          <button class="btn btn-secondary" data-dismiss="modal">Cerrar</button>
        </div>
      </div>
    </div>
  </div>

  <!-- Bootstrap JS -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>

  <script>
    var CSRF = <?= json_encode($csrf) ?>;
    var CURRENT_LUGAR = null;

    function toast(msg) {
      alert(msg);
    }

    function loadAds(q) {
      $('#adsGrid').html('');
      $('#adsEmpty').hide();

      $.post('', { ajax:'list_ads', csrf:CSRF, q: (q || '') }, function(resp){
        if (!resp || !resp.ok) {
          toast(resp && resp.err ? resp.err : 'Error cargando publis');
          return;
        }
        var items = resp.items || [];
        if (!items.length) {
          $('#adsEmpty').show();
          return;
        }

        var html = '';
        for (var i=0; i<items.length; i++) {
          var it = items[i];
          var urlTxt = it.url ? it.url : '';
          var lugarTxt = it.lugar ? ('Lugar actual: ' + it.lugar) : 'Sin lugar';

          html += '<div class="col-12 col-md-3 mb-3">';
          html +=   '<div class="adItem" data-tipo="'+it.tipo+'" data-id="'+it.id+'">';
          html +=     '<img class="adThumb" src="'+it.src+'" ' +
                      (it.src_fallback ? 'onerror="this.onerror=null;this.src=\''+it.src_fallback+'\';"' : '') +
                      ' alt="publi">';
          html +=     '<div class="small mt-2"><b>'+it.tipo+'</b> · ID '+it.id+'</div>';
          html +=     '<div class="small muted">'+lugarTxt+'</div>';
          if (urlTxt) html += '<div class="small" style="word-break:break-all;">'+escapeHtml(urlTxt)+'</div>';
          html +=   '</div>';
          html += '</div>';
        }

        $('#adsGrid').html(html);
      }, 'json');
    }

    function escapeHtml(s){
      return String(s).replace(/[&<>"']/g, function(m){
        return ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'}[m]);
      });
    }

    function assignAd(tipo, id, lugar) {
      $.post('', { ajax:'assign_ad', csrf:CSRF, tipo:tipo, id:id, lugar:lugar }, function(resp){
        if (!resp || !resp.ok) {
          toast(resp && resp.err ? resp.err : 'Error asignando publi');
          return;
        }
        $('#slot-' + lugar).html(resp.html);
        $('#modalAds').modal('hide');
      }, 'json');
    }

    function clearSlot(lugar) {
      $.post('', { ajax:'clear_slot', csrf:CSRF, lugar:lugar }, function(resp){
        if (!resp || !resp.ok) {
          toast(resp && resp.err ? resp.err : 'Error quitando publi');
          return;
        }
        $('#slot-' + lugar).html(resp.html);
      }, 'json');
    }

    // Click “Poner publi”
    $(document).on('click', '.btnPick', function(){
      CURRENT_LUGAR = parseInt($(this).data('lugar'), 10) || null;
      if (!CURRENT_LUGAR) return;
      $('#modalLugarText').text('Lugar a asignar: ' + CURRENT_LUGAR);
      $('#qAds').val('');
      loadAds('');
      $('#modalAds').modal('show');
    });

    // Click “Quitar”
    $(document).on('click', '.btnClear', function(){
      var lugar = parseInt($(this).data('lugar'), 10) || 0;
      if (!lugar) return;
      if (!confirm('Quitar publi del lugar ' + lugar + '?')) return;
      clearSlot(lugar);
    });

    // Click en una publi dentro del modal
    $(document).on('click', '.adItem', function(){
      if (!CURRENT_LUGAR) return;
      var tipo = $(this).data('tipo');
      var id   = parseInt($(this).data('id'), 10) || 0;
      if (!id) return;
      if (!confirm('Asignar esta publi al lugar ' + CURRENT_LUGAR + '?')) return;
      assignAd(tipo, id, CURRENT_LUGAR);
    });

    // Buscar
    $('#btnReloadAds').on('click', function(){
      loadAds($('#qAds').val() || '');
    });
    $('#qAds').on('keydown', function(e){
      if (e.key === 'Enter') {
        e.preventDefault();
        loadAds($('#qAds').val() || '');
      }
    });
  </script>
</body>
</html>