<?php
ob_start(); // Iniciar el búfer de salida al inicio del script
session_start();

// ***** IMPORTANTE: ESTAS LÍNEAS ESTÁN AQUÍ PARA DEPURAR. *****
// UNA VEZ QUE FUNCIONE, CÁMBIALAS A: error_reporting(0); ini_set('display_errors', 0);
error_reporting(E_ALL); // Reporta todos los errores
ini_set('display_errors', 1); // Muestra los errores en la pantalla
// *************************************************************

// --- DATOS DE ADMINISTRADOR DE EJEMPLO ---
$admin_data = [
    'nombre' => 'María Admin',
    'email' => 'maria.admin@example.com',
    'foto_perfil' => 'https://placehold.co/100x100/4c7c59/ffffff?text=MA' // Ejemplo de imagen
];

// --- Lógica PHP para obtener datos de promociones (AHORA SON DATOS DUMMY) ---
$promotions_data_from_db = [
    'promo-1' => [
        'id' => 'promo-1', // ID para JS (string)
        'db_id' => 1,        // ID simulado de la base de datos (numérico)
        'product_name' => 'Ebook: Guía Completa de Publicidad',
        'descripcion' => 'Descubre los secretos para crear campañas publicitarias exitosas en Facebook e Instagram.',
        'price' => 19.99,
        'image_url' => 'https://placehold.co/300x200/c7f0d0/07162d?text=EBOOK+PROMO', // URL de imagen dummy
        'purchase_url' => 'http://orozdesign.com/ebook-link',
        'created_at' => '2024-07-01 10:00:00'
    ],
    'promo-2' => [
        'id' => 'promo-2',
        'db_id' => 2,
        'product_name' => 'Masterclass: Ventas con WhatsApp Business',
        'descripcion' => 'Aprende a transformar tu WhatsApp Business en una máquina de ventas y automatiza tus respuestas.',
        'price' => 49.00,
        'image_url' => 'https://placehold.co/300x200/ffc857/07162d?text=MASTERCLASS',
        'purchase_url' => 'http://orozdesign.com/masterclass-whatsapp',
        'created_at' => '2024-07-05 14:30:00'
    ],
    'promo-3' => [
        'id' => 'promo-3',
        'db_id' => 3,
        'product_name' => 'Auditoría SEO Gratuita (Promoción Limitada)',
        'descripcion' => 'Obtén un análisis completo de tu sitio web y recibe recomendaciones personalizadas para mejorar tu posicionamiento SEO.',
        'price' => 0.00,
        'image_url' => 'https://placehold.co/300x200/9e1428/ffffff?text=SEO+AUDIT',
        'purchase_url' => 'http://orozdesign.com/auditoria-seo',
        'created_at' => '2024-07-10 09:00:00'
    ],
    'promo-4' => [
        'id' => 'promo-4',
        'db_id' => 4,
        'product_name' => 'Plantillas de Email Marketing',
        'descripcion' => 'Colección de plantillas profesionales para tus campañas de email, listas para usar y personalizar.',
        'price' => 25.50,
        'image_url' => 'https://placehold.co/300x200/3d5a80/e0fbff?text=EMAIL+PLANTILLAS',
        'purchase_url' => 'http://orozdesign.com/plantillas-email',
        'created_at' => '2024-06-25 11:00:00' // Promoción del mes pasado para el contador
    ]
];

// Si el array de promociones está vacío, convertirlo a un objeto vacío para JSON
if (empty($promotions_data_from_db)) {
    $promotions_data_from_db = new stdClass();
}

// Lógica para contar nuevas promociones este mes (desde PHP)
$new_promotions_this_month = 0;
$current_month_year = date('Y-m'); // Formato "AAAA-MM"
foreach ((array)$promotions_data_from_db as $promo) {
    // Aseguramos que 'created_at' exista y sea válido antes de intentar crear un DateTime
    if (isset($promo['created_at']) && (new DateTime($promo['created_at']))->format('Y-m') === $current_month_year) {
        $new_promotions_this_month++;
    }
}

// Codificar los datos a JSON para pasarlos a JavaScript
$promotions_json = json_encode($promotions_data_from_db);
$new_promotions_this_month_json = json_encode($new_promotions_this_month);

// Manejo de notificaciones de sesión (si existen)
$notification_message = '';
$notification_type = '';
if (isset($_SESSION['notification'])) {
    $notification_message = $_SESSION['notification']['message'];
    $notification_type = $_SESSION['notification']['type'];
    unset($_SESSION['notification']); // Limpiar la notificación después de mostrarla
}
ob_end_clean(); // Finalizar y limpiar el búfer de salida
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>LocalCRM ToolKit Dashboard | Administración de Promociones</title>
    <meta name="description" content="Administra tus promociones y ofertas especiales en LocalCRM: sube, edita y organiza tus productos destacados.">
    <meta name="robots" content="noindex, nofollow">

    <link rel="icon" type="image/png" href="img/favicon.png">
    <link rel="apple-touch-icon" href="img/apple-touch-icon.png">

    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Barlow:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
    <script src="https://unpkg.com/lucide@latest"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
    
    <link rel="stylesheet" href="style.css">
    <script src="files/header-manager.js"></script>
</head>
 
<body data-page-title="PANEL DE ADMINISTRADOR - PROMOCIONES"
      data-page-subtitle="GESTIÓN DE OFERTAS Y PRODUCTOS"
      data-page-icon="tag">

<div id="toastNotification" class="toast-notification">
    <i id="toastIcon" class="fas"></i>
    <span id="toastMessage"></span>
    <button id="toastCloseBtn" class="toast-close-btn">×</button>
</div>
<style>
.toast-notification {
    visibility: hidden;
    min-width: 250px;
    background-color: #333;
    color: #fff;
    text-align: center;
    border-radius: 8px;
    padding: 16px;
    position: fixed;
    z-index: 1000;
    left: 50%;
    transform: translateX(-50%);
    bottom: 30px;
    font-size: 17px;
    display: flex;
    align-items: center;
    gap: 10px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.2);
    opacity: 0;
    transition: opacity 0.5s, bottom 0.5s;
}

.toast-notification.show {
    visibility: visible;
    opacity: 1;
    bottom: 50px;
}

.toast-notification.success { background-color: #4CAF50; }
.toast-notification.error { background-color: #f44336; }
.toast-notification.info { background-color: #2196F3; }

.toast-notification .toast-close-btn {
    background: none;
    border: none;
    color: white;
    font-size: 20px;
    cursor: pointer;
    margin-left: auto;
}
</style>

<div class="relative min-h-screen md:flex">

    <div id="sidebar-overlay" class="fixed inset-0 bg-black bg-opacity-50 z-30 hidden md:hidden"></div>

    <?php include 'menu.php'; ?>

    <main class="flex-1 overflow-y-auto">
        <header class="bg-white shadow-sm p-4 flex justify-between items-center sticky top-0 z-20">
            <button id="mobile-menu-button" class="md:hidden text-gray-600 hover:text-gray-800">
                <i data-lucide="menu" class="w-6 h-6"></i>
            </button>
            <div class="page-header-container">
                <h2 id="page-title"></h2>
                <p id="page-subtitle"></p>
            </div>
        </header>

        <div id="content-area" class="p-4 md:p-8 space-y-8">
            <section id="promotions" class="dashboard-section">
                <div class="bg-white p-6 rounded-xl shadow-md">
                    <div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-6 gap-4">
                        <div>
                            <h3 class="text-2xl font-extrabold text-gray-800 flex items-center gap-2">
                                <i data-lucide="tag" class="w-7 h-7 text-[var(--color-primary)]"></i> INVENTARIO DE PROMOCIONES
                            </h3>
                            <p class="text-gray-500 text-sm mt-1 uppercase">VISUALIZA Y ADMINISTRA TUS OFERTAS Y PRODUCTOS PROMOCIONALES.</p>
                        </div>
                        <div class="flex items-center gap-4 w-full md:w-auto">
                            <button id="addPromotionBtn" class="btn-secondary font-bold py-2 px-4 rounded-lg flex items-center w-full md:w-auto justify-center uppercase">
                                <i data-lucide="plus" class="w-5 h-5 mr-2"></i> AGREGAR PROMOCIÓN
                            </button>
                            </div>
                    </div>

                    <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
                        <div class="stat-card bg-white p-6 rounded-xl shadow-md flex items-center space-x-4 border-l-4 border-[var(--color-primary)]">
                            <i data-lucide="shopping-cart" class="w-12 h-12 text-gray-700"></i>
                            <div>
                                <h3 class="text-lg font-extrabold text-gray-500 mb-1">TOTAL DE PROMOCIONES</h3>
                                <p id="total-promotions-count" class="text-5xl font-bold text-[var(--color-secondary)]">0</p>
                                <p class="text-sm text-gray-400 mt-1">EN EL CATÁLOGO</p>
                            </div>
                        </div>
                        <div class="stat-card bg-white p-6 rounded-xl shadow-md flex items-center space-x-4 border-l-4 border-[var(--color-highlight)]">
                            <i data-lucide="trending-up" class="w-12 h-12 text-gray-700"></i>
                            <div>
                                <h3 class="text-lg font-extrabold text-gray-500 mb-1">NUEVAS PROMOCIONES ESTE MES</h3>
                                <p id="new-promotions-this-month-count" class="text-5xl font-bold text-[var(--color-secondary)]">0</p>
                                <p class="text-sm text-gray-400 mt-1 uppercase">PROMOCIONES AGREGADAS EN EL PERIODO</p>
                            </div>
                        </div>
                    </div>

                    <div class="flex flex-col md:flex-row gap-4 mb-6">
                        <div class="relative flex-grow">
                            <input type="text" id="promotion-search" placeholder="Buscar Por Nombre o Descripción..." class="w-full p-3 pl-10 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]">
                            <i data-lucide="search" class="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400"></i>
                        </div>
                        <div class="view-toggle inline-flex bg-gray-200 rounded-lg p-1">
                            <button id="grid-view-btn" class="px-3 py-1 rounded-md text-sm font-semibold transition-colors duration-200 active uppercase" title="Vista de Cuadrícula">
                                <i data-lucide="layout-grid" class="w-5 h-5"></i>
                            </button>
                            <button id="list-view-btn" class="px-3 py-1 rounded-md text-sm font-semibold transition-colors duration-200 uppercase" title="Vista de Lista">
                                <i data-lucide="list" class="w-5 h-5"></i>
                            </button>
                        </div>
                    </div>

                    <div id="promotion-grid-view" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                        </div>

                    <div id="promotion-list-view" class="overflow-x-auto hidden">
                        <table class="min-w-full bg-white">
                            <thead class="bg-gray-50">
                                <tr class="text-left text-gray-500 uppercase text-sm">
                                    <th class="py-3 px-6 font-semibold">PRODUCTO</th>
                                    <th class="py-3 px-6 font-semibold hidden md:table-cell">DESCRIPCIÓN</th>
                                    <th class="py-3 px-6 font-semibold">PRECIO</th>
                                    <th class="py-3 px-6 font-semibold">URL COMPRA</th>
                                    <th class="py-3 px-6 font-semibold text-center">ACCIONES</th>
                                </tr>
                            </thead>
                            <tbody class="text-gray-700 text-sm" id="promotionsTableBody">
                                </tbody>
                        </table>
                    </div>

                </div>
            </section>
        </div>
    </main>
</div>

<div id="addPromotionPanel" class="fixed inset-y-0 right-0 w-full md:w-1/2 bg-white shadow-lg transform translate-x-full transition-transform duration-300 ease-in-out z-50 overflow-y-auto">
    <div class="p-8 flex flex-col h-full">
        <div class="flex justify-between items-center mb-6 flex-shrink-0">
            <h3 class="text-2xl font-bold text-[var(--color-primary)]">AGREGAR NUEVA PROMOCIÓN</h3>
            <button onclick="closePanel('addPromotionPanel')" class="text-gray-400 hover:text-gray-600"><i data-lucide="x" class="w-6 h-6"></i></button>
        </div>
        <form id="add-promotion-form" class="flex-grow overflow-y-auto pr-2 -mr-2">
            <div class="grid grid-cols-1 gap-x-6 gap-y-4">
                <div>
                    <label for="promotion-product-name" class="block text-gray-700 text-sm font-bold mb-2 uppercase">NOMBRE DEL PRODUCTO/OFERTA</label>
                    <input type="text" id="promotion-product-name" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="Ej. Ebook de Marketing Digital" required>
                </div>
                <div>
                    <label for="promotion-price" class="block text-gray-700 text-sm font-bold mb-2 uppercase">PRECIO</label>
                    <input type="number" step="0.01" id="promotion-price" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="Ej. 29.99" required>
                </div>
                <div>
                    <label for="promotion-image-url" class="block text-gray-700 text-sm font-bold mb-2 uppercase">URL DE IMAGEN DEL PRODUCTO</label>
                    <input type="url" id="promotion-image-url" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="http://mi-imagen.jpg">
                    <p class="text-xs text-gray-500 mt-1">Sube la imagen a un servicio de hosting y pega el enlace aquí.</p>
                </div>
                 <div>
                    <label for="promotion-purchase-url" class="block text-gray-700 text-sm font-bold mb-2 uppercase">URL PARA COMPRAR</label>
                    <input type="url" id="promotion-purchase-url" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="http://enlace-de-compra.com" required>
                </div>
                <div>
                    <label for="promotion-descripcion" class="block text-gray-700 text-sm font-bold mb-2 uppercase">DESCRIPCIÓN DE LA OFERTA</label>
                    <textarea id="promotion-descripcion" rows="5" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="Describe los beneficios y detalles de la promoción"></textarea>
                </div>
            </div>
            <div class="h-4"></div>
        </form>
        <div class="flex justify-end space-x-4 pt-6 flex-shrink-0">
            <button type="button" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase" onclick="closePanel('addPromotionPanel')">CANCELAR</button>
            <button type="submit" form="add-promotion-form" class="btn-secondary font-bold py-2 px-4 rounded-lg uppercase">GUARDAR PROMOCIÓN</button>
        </div>
    </div>
</div>

<div id="confirmDeleteModal" class="fixed inset-0 bg-gray-900 bg-opacity-75 flex items-center justify-center hidden z-50">
    <div class="bg-white p-8 rounded-xl shadow-2xl w-full max-w-sm m-4 transform transition-all duration-300 scale-95 opacity-0 text-center">
        <div class="flex justify-center mb-4">
            <i data-lucide="alert-triangle" class="w-16 h-16 text-red-500"></i>
        </div>
        <h3 class="text-2xl font-bold text-[var(--color-primary)] mb-4 uppercase">CONFIRMAR ELIMINACIÓN</h3>
        <p class="text-gray-700 mb-6 uppercase">¿ESTÁS SEGURO DE QUE DESEAS ELIMINAR ESTE <span id="confirm-item-type" class="font-semibold">ELEMENTO</span>? ESTA ACCIÓN NO SE PUEDE DESHACER.</p>
        <div class="flex justify-center space-x-4">
            <button type="button" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase" onclick="closeModal('confirmDeleteModal')">CANCELAR</button>
            <button type="button" class="btn-secondary font-bold py-2 px-4 rounded-lg uppercase" id="confirm-delete-button">CONFIRMAR</button>
        </div>
    </div>
</div>

<div id="viewPromotionPanel" class="fixed inset-y-0 right-0 w-full md:w-1/2 bg-white shadow-lg transform translate-x-full transition-transform duration-300 ease-in-out z-50 overflow-y-auto">
    <div class="p-8 flex flex-col h-full">
        <div class="flex justify-between items-center mb-6 flex-shrink-0">
            <h3 class="text-2xl font-bold text-[var(--color-primary)]">DETALLE DE LA PROMOCIÓN</h3>
            <button onclick="closePanel('viewPromotionPanel')" class="text-gray-400 hover:text-gray-600"><i data-lucide="x" class="w-6 h-6"></i></button>
        </div>
        <form id="view-promotion-form" class="flex-grow overflow-y-auto pr-2 -mr-2">
            <input type="hidden" id="view-promotion-id">
            <div class="grid grid-cols-1 gap-x-6 gap-y-4">
                <div>
                    <label for="view-promotion-product-name" class="block text-gray-700 text-sm font-bold mb-2 uppercase">NOMBRE DEL PRODUCTO/OFERTA</label>
                    <input type="text" id="view-promotion-product-name" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="Nombre Del Producto">
                </div>
                <div>
                    <label for="view-promotion-price" class="block text-gray-700 text-sm font-bold mb-2 uppercase">PRECIO</label>
                    <input type="number" step="0.01" id="view-promotion-price" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="Ej. 50.00">
                </div>
                <div>
                    <label for="view-promotion-image-url" class="block text-gray-700 text-sm font-bold mb-2 uppercase">URL DE IMAGEN DEL PRODUCTO</label>
                    <input type="url" id="view-promotion-image-url" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="http://mi-imagen.jpg">
                </div>
                <div class="md:col-span-2">
                    <label class="block text-gray-700 text-sm font-bold mb-2 uppercase">PREVISUALIZACIÓN DE IMAGEN</label>
                    <div id="promotion-image-preview" class="w-full h-40 bg-gray-200 rounded-lg flex items-center justify-center text-gray-500 overflow-hidden">
                        <i data-lucide="image" class="w-12 h-12"></i>
                    </div>
                    <p class="text-xs text-gray-500 mt-2">La imagen se cargará automáticamente desde la URL.</p>
                </div>
                 <div>
                    <label for="view-promotion-purchase-url" class="block text-gray-700 text-sm font-bold mb-2 uppercase">URL PARA COMPRAR</label>
                    <input type="url" id="view-promotion-purchase-url" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="http://enlace-de-compra.com">
                </div>
                <div>
                    <label for="view-promotion-descripcion" class="block text-gray-700 text-sm font-bold mb-2 uppercase">DESCRIPCIÓN DE LA OFERTA</label>
                    <textarea id="view-promotion-descripcion" rows="5" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="Descripción Detallada De La Promoción"></textarea>
                </div>
            </div>
            <div class="h-4"></div>
        </form>
        <div class="flex justify-end space-x-4 pt-4 border-t border-gray-200 mt-6 flex-shrink-0">
            <button type="button" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase" onclick="closePanel('viewPromotionPanel')">CANCELAR</button>
            <button type="submit" form="view-promotion-form" class="btn-primary font-bold py-2 px-4 rounded-lg uppercase">GUARDAR CAMBIOS</button>
        </div>
    </div>
</div>

<script>
// Variable global para almacenar las promociones cargadas desde PHP
// Se usa una IIFE (Immediately Invoked Function Expression) con try-catch para un parseo seguro.
let promotionsActuales = (function() {
    try {
        const data = <?php echo $promotions_json; ?>;
        // Asegúrate de que los datos sean un objeto, no un array vacío ni nulo.
        return (typeof data === 'object' && data !== null && !Array.isArray(data)) ? data : {};
    } catch (e) {
        console.error("Error al parsear promotions_json:", e);
        return {}; // Devuelve un objeto vacío en caso de error
    }
})();

// El contador de promociones nuevas este mes ya viene de PHP, lo asignamos directamente.
// NOTA: En la lógica de JS, este contador se recalculará dinámicamente.
let newPromotionsThisMonthCount = <?php echo $new_promotions_this_month_json; ?>;


document.addEventListener('DOMContentLoaded', function() {
    // --- CONSOLE.LOGS PARA DEPURACIÓN (visible en la consola del navegador) ---
    console.log("--- Depuración de promote.php ---");
    console.log("promotionsActuales (datos de promociones de la DB al cargar PHP):", promotionsActuales);
    console.log("newPromotionsThisMonthCount (contador mensual desde PHP):", newPromotionsThisMonthCount);
    // --- FIN CONSOLE.LOGS PARA DEPURACIÓN ---


    // --- VARIABLES DOM LOCALES (Elementos HTML que el JS necesita manipular) ---
    const mobileMenuButton = document.getElementById('mobile-menu-button');
    const sidebar = document.getElementById('sidebar');
    const sidebarOverlay = document.getElementById('sidebar-overlay');
    const sidebarCloseBtn = document.getElementById('sidebarCloseBtn'); // Botón de cierre explícito del sidebar
    
    // Promociones
    const promotionSearch = document.getElementById('promotion-search');
    const promotionGridView = document.getElementById('promotion-grid-view');
    const promotionListView = document.getElementById('promotion-list-view');
    const promotionsTableBody = document.getElementById('promotionsTableBody');
    const gridViewBtn = document.getElementById('grid-view-btn');
    const listViewBtn = document.getElementById('list-view-btn');
    // ELIMINADO: const downloadPromotionsBtn = document.getElementById('download-promotions-btn'); // Botón de descarga
    const addPromotionForm = document.getElementById('add-promotion-form');
    const viewPromotionForm = document.getElementById('view-promotion-form');
    const totalPromotionsCountElement = document.getElementById('total-promotions-count');
    const newPromotionsThisMonthCountElement = document.getElementById('new-promotions-this-month-count');
    // **IMPORTANTE**: Asegúrate que este ID 'addPromotionBtn' esté en tu HTML para el botón de "Agregar Promoción"
    const addPromotionBtn = document.getElementById('addPromotionBtn'); 

    // Referencias para el panel de ver/editar promoción
    const addPromotionImageUrlInput = document.getElementById('promotion-image-url'); // Input para URL de imagen en el formulario de añadir
    const viewPromotionImageUrlInput = document.getElementById('view-promotion-image-url'); // Input para URL de imagen en el formulario de ver/editar
    const promotionImagePreview = document.getElementById('promotion-image-preview'); // Preview de imagen (compartida para añadir/editar)

    // Modales de confirmación (compartidos)
    const confirmDeleteModal = document.getElementById('confirmDeleteModal');
    const confirmDeleteButton = document.getElementById('confirm-delete-button');
    const confirmItemTypeSpan = document.getElementById('confirm-item-type');


    // Variable para controlar la vista actual de las promociones (cuadrícula por defecto)
    let currentPromotionView = 'grid'; 
    
    // Elemento de overlay para los paneles laterales (creado dinámicamente si no existe)
    // Esto es para el fondo oscuro semitransparente cuando se abre un panel lateral.
    let panelOverlay = document.getElementById('panel-overlay');
    if (!panelOverlay) {
        panelOverlay = document.createElement('div');
        panelOverlay.id = 'panel-overlay';
        panelOverlay.className = 'fixed inset-0 bg-black bg-opacity-50 z-40 hidden';
        document.body.appendChild(panelOverlay);
    }


    // --- FUNCIONES HELPER GLOBALES (acciones comunes que pueden ser llamadas desde cualquier parte) ---

    // Muestra una notificación temporal en la pantalla (como un "toast")
    window.showCustomNotification = function(message, type = 'info', duration = 3000) {
        const toast = document.getElementById('toastNotification');
        const toastMessage = document.getElementById('toastMessage');
        const toastIcon = document.getElementById('toastIcon');
        const toastCloseBtn = document.getElementById('toastCloseBtn');
        let toastTimeout;

        // Si los elementos del toast no existen, imprime un mensaje en consola y no hace nada
        if (!toast || !toastMessage || !toastIcon || !toastCloseBtn) {
            console.warn(`[NOTIFICACION - FALLBACK] Elementos de toast no encontrados. Mensaje: ${type.toUpperCase()}: ${message}`);
            return;
        }

        clearTimeout(toastTimeout); // Limpia cualquier notificación anterior
        // Limpiar clases de tipo anteriores para aplicar la nueva
        toast.classList.remove('success', 'error', 'info');
        toastIcon.classList.remove('fa-check-circle', 'fa-exclamation-circle', 'fa-info-circle');
        toast.className = 'toast-notification'; // Restablecer a la clase base

        toastMessage.textContent = message; // Establece el mensaje
        toast.classList.add(type); // Añade la clase de estilo (success, error, info)
        
        // Define el ícono basado en el tipo de notificación
        if (type === 'success') {
            toastIcon.classList.add('fa-check-circle');
        } else if (type === 'error') {
            toastIcon.classList.add('fa-exclamation-circle');
        } else {
            toastIcon.classList.add('fa-info-circle'); 
        }

        toast.classList.add('show'); // Muestra el toast
        // Configura un temporizador para ocultar el toast después de 'duration' milisegundos
        toastTimeout = setTimeout(() => {
            toast.classList.remove('show');
        }, duration);

        // Permite cerrar el toast manualmente
        toastCloseBtn.onclick = () => {
            clearTimeout(toastTimeout);
            toast.classList.remove('show');
        };

        console.log(`[NOTIFICACION - ${type.toUpperCase()}] ${message}`);
    };

    // Abre un panel lateral deslizante (como los de añadir/editar)
    window.openPanel = function(panelId) {
        const panel = document.getElementById(panelId);
        if (!panel) { console.error(`Error: Panel con ID "${panelId}" no encontrado.`); return; }
        panel.classList.remove('translate-x-full'); // Mueve el panel para que sea visible
        panelOverlay.classList.remove('hidden');    // Muestra el overlay oscuro
        console.log(`[promote.php] Panel ${panelId} abierto.`);
        
        // Lógica específica para restablecer formularios al abrir
        if (panelId === 'addPromotionPanel') {
            addPromotionForm.reset(); // Limpia el formulario
            addPromotionImageUrlInput.value = ''; // Limpia la URL de imagen al añadir
            // Restablece la previsualización de imagen al icono por defecto
            promotionImagePreview.innerHTML = `<i data-lucide="image" class="w-12 h-12 text-gray-500"></i>`;
            lucide.createIcons({ container: promotionImagePreview });
        } 
        // No es necesario manejar viewPromotionPanel aquí, openViewPromotionModal ya lo llena
    };

    // Cierra un panel lateral deslizante
    window.closePanel = function(panelId) {
        const panel = document.getElementById(panelId);
        if (!panel) { console.error(`Error: Panel con ID "${panelId}" no encontrado para cerrar.`); return; }
        panel.classList.add('translate-x-full'); // Esconde el panel
        panelOverlay.classList.add('hidden');    // Esconde el overlay
        console.log(`[promote.php] Panel ${panelId} cerrado.`);
    };

    // Abre un modal (ventana emergente, como la de confirmación de eliminación)
    window.openModal = function(modalId) {
        const modal = document.getElementById(modalId);
        if (!modal) { console.error(`Error: Modal con ID "${modalId}" no encontrado.`); return; }
        const modalBox = modal.querySelector('div:first-of-type'); // El contenido real del modal
        modal.classList.remove('hidden'); // Muestra el modal
        // Pequeño retardo para la animación de entrada
        setTimeout(() => { 
            if (modalBox) modalBox.classList.remove('scale-95', 'opacity-0'); 
        }, 50);
        console.log(`[promote.php] Modal ${modalId} abierto.`);
        lucide.createIcons({ container: modal }); // Asegura que los íconos del modal se muestren
    };

    // Cierra un modal
    window.closeModal = function(modalId) {
        const modal = document.getElementById(modalId);
        if (!modal) { console.error(`Error: Modal con ID "${modalId}" no encontrado para cerrar.`); return; }
        const modalBox = modal.querySelector('div:first-of-type');
        if (modalBox) modalBox.classList.add('scale-95', 'opacity-0'); // Inicia la animación de salida
        // Oculta el modal después de la animación
        setTimeout(() => { modal.classList.add('hidden'); }, 300);
        console.log(`[promote.php] Modal ${modalId} cerrado.`);
    };
    
    // Prepara y abre el modal de confirmación de eliminación para un elemento específico
    window.openConfirmDeleteModal = function(itemId, itemType) {
        if (!confirmDeleteButton || !confirmItemTypeSpan) { console.error("Error: Elementos del modal de confirmación de eliminación no encontrados."); return; }
        confirmDeleteButton.dataset.itemId = itemId; // Guarda el ID del elemento a eliminar
        confirmDeleteButton.dataset.itemType = itemType; // Guarda el tipo (promoción)
        confirmItemTypeSpan.textContent = itemType.toUpperCase(); // Muestra el tipo en el mensaje
        openModal('confirmDeleteModal'); // Abre el modal
    };

    // ELIMINADO: Función descargarComoCSV ya no es necesaria
    /*
    function descargarComoCSV(dataObject, filename) {
        const data = Object.values(dataObject);
        if (data.length === 0) { showCustomNotification('No hay datos para descargar.', 'info'); return; }
        const escapeCSV = (value) => {
            if (value === null || value === undefined) { return ''; }
            value = String(value);
            if (value.search(/("|,|\n)/g) >= 0) { return `"${value.replace(/"/g, '""')}"`; }
            return value;
        };
        const headers = ['db_id', 'product_name', 'descripcion', 'price', 'image_url', 'purchase_url', 'created_at']; 
        const csvRows = [headers.map(h => escapeCSV(h.replace(/_/g, ' ').toUpperCase())).join(',')];
        data.forEach(item => {
            const values = headers.map(header => escapeCSV(item[header]));
            csvRows.push(values.join(','));
        });
        const csvContent = csvRows.join('\n');
        const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
        const link = document.createElement('a');
        if (link.download !== undefined) {
            const url = URL.createObjectURL(blob);
            link.setAttribute('href', url); 
            link.setAttribute('download', filename);
            link.style.visibility = 'hidden'; 
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            showCustomNotification('CSV generado y descargado.', 'success');
        } else {
            showCustomNotification('Tu navegador no soporta la descarga directa de archivos.', 'error');
        }
    }
    */

    // Abre el panel de Ver/Editar Promoción
    window.openViewPromotionModal = function(promotionId) {
        const promotion = promotionsActuales[promotionId];
        if (!promotion) { console.error('Promoción no encontrada:', promotionId); return; }
        
        // Rellena los campos del formulario con los datos de la promoción
        document.getElementById('view-promotion-id').value = promotion.db_id;
        document.getElementById('view-promotion-product-name').value = promotion.product_name;
        document.getElementById('view-promotion-price').value = promotion.price;
        document.getElementById('view-promotion-image-url').value = promotion.image_url || '';
        document.getElementById('view-promotion-purchase-url').value = promotion.purchase_url || '';
        document.getElementById('view-promotion-descripcion').value = promotion.descripcion || '';

        // Actualizar la imagen de previsualización
        if (promotionImagePreview) { // Asegúrate de que el elemento exista
            if (promotion.image_url) {
                promotionImagePreview.innerHTML = `<img src="${promotion.image_url}" alt="Miniatura de promoción" class="w-full h-full object-cover rounded-lg">`;
            } else {
                promotionImagePreview.innerHTML = `<i data-lucide="image" class="w-12 h-12 text-gray-500"></i>`;
            }
            lucide.createIcons({ container: promotionImagePreview }); // Re-renderiza íconos si se muestra el placeholder
        }

        openPanel('viewPromotionPanel'); // Abre el panel
    };

    // Setup de listeners para botones de eliminar
    function setupDeleteListeners() {
        document.querySelectorAll('.delete-btn').forEach(button => {
            button.removeEventListener('click', handleDeleteButtonClick); // Previene múltiples listeners
            button.addEventListener('click', handleDeleteButtonClick);
        });
    }
    function handleDeleteButtonClick(e) {
        e.stopPropagation(); // Evita que el clic se propague
        const itemId = this.dataset.itemId; // Obtiene el ID del elemento a eliminar
        const itemType = this.dataset.itemType; // Obtiene el tipo de elemento (promoción)
        openConfirmDeleteModal(itemId, itemType); // Abre el modal de confirmación
    }

    // Setup de listeners para botones de ver/editar
    function setupEditListeners() {
        document.querySelectorAll('.edit-promotion-btn').forEach(button => {
            button.removeEventListener('click', handleEditPromotionButtonClick); // Previene múltiples listeners
            button.addEventListener('click', handleEditPromotionButtonClick);
        });
    }
    function handleEditPromotionButtonClick(e) {
        e.stopPropagation(); // Evita que el clic se propague
        const promotionId = this.dataset.promotionId;
        openViewPromotionModal(promotionId); // Abre el panel de edición de la promoción
    }
    
    // Función para actualizar el conteo total de promociones en el dashboard
    function updateTotalPromotionsDisplay() {
        if (totalPromotionsCountElement) {
            const total = Object.keys(promotionsActuales).length;
            totalPromotionsCountElement.textContent = total.toString();
        }
    }

    // Función para actualizar el contador de promociones nuevas este mes en el dashboard
    function updateNewPromotionsThisMonthDisplay() {
        if (newPromotionsThisMonthCountElement) {
            // Recalcula el contador real en lugar de usar el dummy de PHP
            let newThisMonth = 0;
            const currentMonth = new Date().getMonth();
            const currentYear = new Date().getFullYear();
            Object.values(promotionsActuales).forEach(promo => {
                if (promo.created_at) {
                    const createdAt = new Date(promo.created_at);
                    if (createdAt.getFullYear() === currentYear && createdAt.getMonth() === currentMonth) {
                        newThisMonth++;
                    }
                }
            });
            newPromotionsThisMonthCountElement.textContent = newThisMonth.toString();
        }
    }

    // Crea el HTML para una tarjeta de promoción (vista de cuadrícula)
    function renderPromotionCard(promotion) {
        const card = document.createElement('div');
        card.className = 'bg-white rounded-xl shadow-md overflow-hidden flex flex-col border border-gray-200';
        card.dataset.promotionId = promotion.id;
        card.dataset.itemId = promotion.id;

        const imageUrl = promotion.image_url || '';
        const imageHtml = imageUrl ? 
            `<img src="${imageUrl}" alt="Imagen de ${promotion.product_name}" class="w-full h-32 object-cover">` :
            `<div class="w-full h-32 bg-gray-200 flex items-center justify-center text-gray-500"><i data-lucide="image" class="w-12 h-12"></i></div>`;

        card.innerHTML = `
            <div class="relative">
                ${imageHtml}
                <div class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-50 text-white opacity-0 hover:opacity-100 transition-opacity duration-300 cursor-pointer" onclick="openViewPromotionModal('${promotion.id}')">
                    <i data-lucide="eye" class="w-16 h-16"></i>
                </div>
            </div>
            <div class="p-4 flex-grow flex flex-col">
                <h3 class="font-bold text-lg text-gray-800 mb-2 uppercase line-clamp-2">${promotion.product_name}</h3>
                <p class="text-[var(--color-secondary)] font-extrabold text-2xl mb-2">$${parseFloat(promotion.price).toFixed(2)}</p>
                <p class="text-gray-700 text-sm flex-grow mb-4 line-clamp-3">${promotion.descripcion || 'Sin descripción detallada.'}</p>
                <p class="text-gray-500 text-xs mt-auto">Agregado: <span class="font-semibold">${new Date(promotion.created_at).toLocaleDateString()}</span></p>
            </div>
            <div class="bg-gray-100 p-3 flex justify-end space-x-3 border-t border-gray-200">
                <a href="${promotion.purchase_url}" target="_blank" class="bg-blue-100 hover:bg-blue-200 text-blue-600 font-semibold py-2 px-4 rounded-lg text-sm uppercase inline-flex items-center justify-center gap-1">
                    <i data-lucide="external-link" class="w-4 h-4"></i> Ir
                </a>
                <button class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-semibold py-2 px-4 rounded-lg text-sm uppercase edit-promotion-btn" data-promotion-id="${promotion.id}">EDITAR</button>
                <button class="p-2 bg-red-100 hover:bg-red-200 text-red-600 rounded-lg delete-btn" data-item-type="promoción" data-item-id="${promotion.id}" title="ELIMINAR PROMOCIÓN"><i data-lucide="trash-2" class="w-5 h-5"></i></button>
            </div>
        `;
        lucide.createIcons({ container: card }); // Renderiza los íconos de Lucide dentro de la tarjeta
        return card;
    }

    // Crea el HTML para una fila de tabla de promoción (vista de lista)
    function renderPromotionTableRow(promotion) {
        const row = document.createElement('tr');
        row.className = 'border-b border-gray-200 hover:bg-gray-50';
        row.dataset.promotionId = promotion.id;
        row.dataset.itemId = promotion.id;

        const shortDescription = promotion.descripcion ? promotion.descripcion.substring(0, 70) + (promotion.descripcion.length > 70 ? '...' : '') : 'N/A';

        row.innerHTML = `
            <td class="py-4 px-6 whitespace-nowrap">
                <span class="text-blue-600 hover:text-blue-800 cursor-pointer font-semibold uppercase" onclick="openViewPromotionModal('${promotion.id}')">${promotion.product_name}</span>
            </td>
            <td class="py-4 px-6 hidden md:table-cell uppercase">${shortDescription}</td>
            <td class="py-4 px-6 uppercase">$${parseFloat(promotion.price).toFixed(2)}</td>
            <td class="py-4 px-6">
                <a href="${promotion.purchase_url}" target="_blank" class="text-blue-500 hover:underline flex items-center gap-1">
                    <i data-lucide="external-link" class="w-4 h-4"></i> Enlace
                </a>
            </td>
            <td class="py-4 px-6 text-center">
                <button class="text-blue-600 hover:text-blue-800 mr-3 edit-promotion-btn" title="EDITAR PROMOCIÓN" data-promotion-id="${promotion.id}"><i data-lucide="edit-2" class="w-5 h-5"></i></button>
                <button class="text-red-600 hover:text-red-800 delete-btn" data-item-type="promoción" data-item-id="${promotion.id}" title="ELIMINAR PROMOCIÓN"><i data-lucide="trash-2" class="w-5 h-5"></i></button>
            </td>
        `;
        lucide.createIcons({ container: row }); // Renderiza los íconos de Lucide dentro de la fila
        return row;
    }

    // Renderiza (dibuja) todas las promociones en la vista seleccionada (cuadrícula o lista)
    function renderPromotions(viewType = currentPromotionView) {
        // Verifica que todos los elementos HTML necesarios existan antes de intentar manipularlos
        if (!promotionGridView || !promotionListView || !promotionsTableBody || !promotionSearch || !gridViewBtn || !listViewBtn) {
               console.error("[promote.php] ERROR: Elementos DOM de Promociones no encontrados. Verifique los IDs de los elementos HTML."); return;
        }
        const searchTerm = promotionSearch.value.toLowerCase(); // Obtiene el texto de búsqueda

        // Convierte el objeto de promociones a un array para poder filtrarlo
        const allPromotionsArray = Object.values(promotionsActuales);

        console.log("renderPromotions: promotionsActuales antes de filtrar:", allPromotionsArray); // Depuración

        // Filtra las promociones según el término de búsqueda
        const filteredPromotions = allPromotionsArray.filter(p => {
            const matchesSearch = searchTerm === '' || 
                                    (p.product_name && p.product_name.toLowerCase().includes(searchTerm)) || 
                                    (p.descripcion && p.descripcion.toLowerCase().includes(searchTerm)) || 
                                    (p.purchase_url && p.purchase_url.toLowerCase().includes(searchTerm));
            return matchesSearch;
        });

        console.log("renderPromotions: promociones filtradas:", filteredPromotions); // Depuración


        promotionGridView.innerHTML = ''; // Limpia la vista de cuadrícula
        promotionsTableBody.innerHTML = ''; // Limpia la tabla

        if (filteredPromotions.length === 0) {
            // Muestra un mensaje si no se encuentran promociones
            const message = `<p class="text-gray-500 md:col-span-2 lg:col-span-3 text-center uppercase">NO SE ENCONTRARON PROMOCIONES.</p>`;
            if (viewType === 'grid') {
                promotionGridView.innerHTML = message;
            } else {
                promotionsTableBody.innerHTML = `<tr><td colspan="5" class="py-4 px-6 text-center text-gray-500 uppercase">NO SE ENCONTRARON PROMOCIONES.</td></tr>`;
            }
        } else {
            // Renderiza las promociones en la vista seleccionada
            if (viewType === 'grid') {
                filteredPromotions.forEach(promotion => promotionGridView.appendChild(renderPromotionCard(promotion)));
            } else {
                filteredPromotions.forEach(promotion => promotionsTableBody.appendChild(renderPromotionTableRow(promotion)));
            }
        }

        // Corrige la visibilidad de las vistas y el estado activo de los botones
        if (viewType === 'grid') {
            promotionGridView.classList.remove('hidden');
            promotionListView.classList.add('hidden');
            gridViewBtn.classList.add('active');
            listViewBtn.classList.remove('active');
        } else { // viewType === 'list'
            promotionGridView.classList.add('hidden');
            promotionListView.classList.remove('hidden');
            gridViewBtn.classList.remove('active');
            listViewBtn.classList.add('active');
        }

        // Vuelve a configurar los listeners para los botones de eliminar y editar (necesario después de cada renderizado)
        setupDeleteListeners();
        setupEditListeners();
        // Los iconos de Lucide ya se crean dentro de renderPromotionCard/renderPromotionTableRow
    }
    
    // Funciones de formato de teléfono (no usadas en esta página, pero mantenidas para consistencia)
    function formatPhoneNumber(value) {
        if (!value) return '';
        const cleaned = ('' + value).replace(/\D/g, '');    
        const match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
        if (match) {
            return `(${match[1]}) ${match[2]}-${match[3]}`;
        }
        return cleaned;    
    }

    function applyInputPhoneFormat(inputElement) {
        if (!inputElement) return;
        inputElement.value = formatPhoneNumber(inputElement.value);
        inputElement.addEventListener('input', (e) => {
            let value = e.target.value.replace(/\D/g, '');    
            e.target.value = formatPhoneNumber(value);
        });
        inputElement.addEventListener('blur', (e) => {
            e.target.value = formatPhoneNumber(e.target.value);
        });
    }

    function applyPhoneFormatToInputs() {
        // No hay campos de teléfono en esta página de promociones.
    }


    // --- INICIALIZACIÓN DE LA PÁGINA ---
    // Esta es la función principal que se ejecuta una vez que el DOM está completamente cargado.

    // 1. Mostrar notificación PHP si existe
    const phpNotificationMessage = "<?php echo addslashes($notification_message); ?>";
    const phpNotificationType = "<?php echo addslashes($notification_type); ?>";
    if (phpNotificationMessage) {
        showCustomNotification(phpNotificationMessage, phpNotificationType);
    }

    // 2. Configurar eventos de la barra lateral (menú móvil)
    if (mobileMenuButton) {
        // Asegúrate de que `toggleSidebar` esté definido en `files/header-manager.js`
        mobileMenuButton.addEventListener('click', typeof toggleSidebar === 'function' ? toggleSidebar : () => console.error('toggleSidebar function not found'));
    }

    // Cierra paneles y overlay si se hace clic en el overlay del sidebar (para móviles)
    if (sidebarOverlay) {
        sidebarOverlay.addEventListener('click', () => {
            if (typeof toggleSidebar === 'function') toggleSidebar();
            closePanel('addPromotionPanel'); 
            closePanel('viewPromotionPanel');
        });
    }
    // Este listener en panelOverlay es crucial para cerrar los paneles laterales cuando se hace clic fuera de ellos
    if (panelOverlay) {
        panelOverlay.addEventListener('click', () => {    
            closePanel('addPromotionPanel');
            closePanel('viewPromotionPanel');
        });
    }
    if (sidebarCloseBtn) {
        if (typeof toggleSidebar === 'function') sidebarCloseBtn.addEventListener('click', toggleSidebar);
    }
    
    // Define `toggleSidebar` si no existe en `header-manager.js` (para evitar errores si no está cargada)
    if (typeof window.toggleSidebar === 'undefined') {
        window.toggleSidebar = function() {
            const sidebarElement = document.getElementById('sidebar');
            const sidebarOverlayElement = document.getElementById('sidebar-overlay');
            if (sidebarElement && sidebarOverlayElement) {
                sidebarElement.classList.toggle('-translate-x-full');
                sidebarOverlayElement.classList.toggle('hidden');
            }
        };
    }


    // --- PROMOCIONES: Lógica de inicialización y eventos ---
    updateTotalPromotionsDisplay(); // Actualiza el conteo total de promociones al cargar la página
    updateNewPromotionsThisMonthDisplay(); // Actualiza el contador de promociones nuevas este mes
    renderPromotions(currentPromotionView); // Renderiza las promociones inicialmente en la vista de cuadrícula
    console.log("[promote.php] Promociones renderizadas.");

    // Evento de búsqueda para promociones
    if (promotionSearch) promotionSearch.addEventListener('input', () => renderPromotions(currentPromotionView));

    // ELIMINADO: Lógica para el botón de descarga CSV
    /*
    if(downloadPromotionsBtn) {
        downloadPromotionsBtn.addEventListener('click', () => {
            // Los datos ya están en promotionsActuales directamente desde PHP, listos para descargar
            descargarComoCSV(promotionsActuales, 'catalogo_promociones.csv');
        });
    }
    */
    
    // Lógica para el botón de confirmación de eliminación (compartido para promociones)
    if (confirmDeleteButton) {
        confirmDeleteButton.addEventListener('click', function() {
            const itemId = this.dataset.itemId;
            const itemType = this.dataset.itemType; // 'promoción'
            
            if (itemType === 'promoción') {
                if (promotionsActuales[itemId]) { 
                    // Simulamos que la eliminación fue exitosa
                    const data = { success: true, message: "Promoción eliminada simuladamente." };
                    if (data.success) {
                        closeModal('confirmDeleteModal');
                        showCustomNotification('Promoción eliminada con éxito (simulado).', 'success');
                        delete promotionsActuales[itemId]; // Elimina la promoción del objeto de datos
                        updateTotalPromotionsDisplay(); // Actualiza el contador total
                        updateNewPromotionsThisMonthDisplay(); // Actualiza el contador mensual
                        renderPromotions(currentPromotionView); // Vuelve a dibujar la lista de promociones
                    } else {
                        showCustomNotification('Error al eliminar promoción (simulado): ' + data.message, 'error');
                    }
                } else {
                    showCustomNotification('Error: Promoción no encontrada para eliminar (simulado).', 'error');
                }
            }
        });
    }

    // Manejo de clics para los botones de vista (cuadrícula/lista) para promociones
    if (gridViewBtn) {
        gridViewBtn.addEventListener('click', () => {
            currentPromotionView = 'grid';
            renderPromotions('grid');
        });
    }
    if (listViewBtn) {
        listViewBtn.addEventListener('click', () => {
            currentPromotionView = 'list';
            renderPromotions('list');
        });
    }

    // Lógica para el formulario de añadir nuevas promociones
    if (addPromotionForm) {
        addPromotionForm.addEventListener('submit', async function(e) {    
            e.preventDefault(); // Previene el envío del formulario tradicional
            const promotionData = {
                product_name: document.getElementById('promotion-product-name').value,
                price: parseFloat(document.getElementById('promotion-price').value), // Convertir a número
                image_url: document.getElementById('promotion-image-url').value,
                purchase_url: document.getElementById('promotion-purchase-url').value,
                descripcion: document.getElementById('promotion-descripcion').value
            };

            try {    
                // Generar un ID único para la nueva promoción simulada
                const currentPromotionValues = Object.values(promotionsActuales);
                // Si no hay promociones, empieza en 0 para que Math.max funcione. Luego +1.
                const currentPromotionIds = currentPromotionValues.length > 0 ? currentPromotionValues.map(p => parseInt(p.id.replace('promo-', '')) || 0) : [0];
                const newIdNumeric = Math.max(...currentPromotionIds) + 1; // Encuentra el ID numérico más alto y le suma 1
                const newId = 'promo-' + newIdNumeric; // El ID de string para usar como clave en el objeto JS

                // Simulación de respuesta de éxito del "servidor"
                const data = {    
                    success: true,    
                    message: "Promoción agregada simuladamente.",
                    promotion: { // Simular la promoción que devolvería el backend
                        id: newIdNumeric, // Esto simula el ID que la base de datos daría
                        product_name: promotionData.product_name,
                        price: promotionData.price,
                        image_url: promotionData.image_url,
                        purchase_url: promotionData.purchase_url,
                        descripcion: promotionData.descripcion,
                        created_at: new Date().toISOString().slice(0, 19).replace('T', ' ') // Fecha actual
                    }
                };

                if (data.success) {
                    closePanel('addPromotionPanel'); // Cierra el panel
                    addPromotionForm.reset(); // Limpia el formulario
                    showCustomNotification('Promoción agregada con éxito (simulado).', 'success');
                    // Añade la nueva promoción a nuestro objeto de datos simulados
                    promotionsActuales[newId] = {    
                        id: newId, // El ID de string
                        db_id: data.promotion.id, // El ID numérico simulado
                        product_name: data.promotion.product_name,
                        descripcion: data.promotion.descripcion,
                        price: data.promotion.price,
                        image_url: data.promotion.image_url,
                        purchase_url: data.promotion.purchase_url,
                        created_at: data.promotion.created_at
                    };
                    updateTotalPromotionsDisplay(); // Actualiza los contadores
                    updateNewPromotionsThisMonthDisplay(); // Actualiza el contador mensual
                    renderPromotions(currentPromotionView); // Vuelve a dibujar las promociones para mostrar la nueva
                } else {
                    showCustomNotification('Error al agregar promoción (simulado): ' + (data.message || 'Error desconocido.'), 'error');
                }
            } catch (error) {
                showCustomNotification('Error de conexión al agregar la promoción (simulado).', 'error');
                console.error('Create promotion error (simulado):', error);
            }
        });
    }

    // Lógica para el formulario de ver/editar promociones
    if (viewPromotionForm) {
        viewPromotionForm.addEventListener('submit', async function(e) {    
            e.preventDefault(); // Previene el envío del formulario tradicional
            const promotionData = {
                id: document.getElementById('view-promotion-id').value, // Esto es el `db_id` numérico
                product_name: document.getElementById('view-promotion-product-name').value,
                price: parseFloat(document.getElementById('view-promotion-price').value), // Convertir a número
                image_url: document.getElementById('view-promotion-image-url').value,
                purchase_url: document.getElementById('view-promotion-purchase-url').value,
                descripcion: document.getElementById('view-promotion-descripcion').value
            };
            
            try {    
                // Encontrar el ID de string (ej. 'promo-1') que corresponde al db_id
                let internalIdToUpdate = null;
                for (const key in promotionsActuales) {
                    if (promotionsActuales[key].db_id == promotionData.id) {
                        internalIdToUpdate = key;
                        break;
                    }
                }

                if (!internalIdToUpdate) {
                    showCustomNotification('Error: Promoción no encontrada para actualizar (simulado).', 'error');
                    console.error('Update promotion error (simulado): Internal ID not found for db_id', promotionData.id);
                    return;
                }

                // Simulación de respuesta de éxito del "servidor"
                const data = {    
                    success: true,    
                    message: "Cambios guardados simuladamente.",
                    promotion: { // Simula la promoción actualizada
                        id: promotionData.id, // El db_id que se "envió"
                        product_name: promotionData.product_name,
                        price: promotionData.price,
                        image_url: promotionData.image_url,
                        purchase_url: promotionData.purchase_url,
                        descripcion: promotionData.descripcion,
                        // Mantenemos la fecha de creación original para la simulación
                        created_at: promotionsActuales[internalIdToUpdate].created_at    
                    }
                };

                if (data.success) {
                    closePanel('viewPromotionPanel'); // Cierra el panel
                    showCustomNotification('Cambios guardados con éxito (simulado).', 'success');
                    // Actualiza la promoción en nuestro objeto de datos simulados
                    if (promotionsActuales[internalIdToUpdate]) {
                        promotionsActuales[internalIdToUpdate] = {
                            id: internalIdToUpdate, // Mantener el ID interno
                            db_id: data.promotion.id, // Actualizar el db_id
                            product_name: data.promotion.product_name,
                            descripcion: data.promotion.descripcion,
                            price: data.promotion.price,
                            image_url: data.promotion.image_url,
                            purchase_url: data.promotion.purchase_url,
                            created_at: data.promotion.created_at
                        };
                    }
                    renderPromotions(currentPromotionView); // Vuelve a dibujar las promociones para mostrar los cambios
                } else {
                    showCustomNotification('Error al guardar cambios (simulado): ' + (data.message || 'Error desconocido.'), 'error');
                }
            } catch (error) {
                showCustomNotification('Error de conexión al guardar los cambios (simulado).', 'error');
                console.error('Update promotion error (simulado):', error);
            }
        });
    }

    // Listener para actualizar la imagen de previsualización en el panel de edición cuando cambia la URL
    if (viewPromotionImageUrlInput && promotionImagePreview) {
        viewPromotionImageUrlInput.addEventListener('input', function() {
            const url = this.value;
            if (url) {
                promotionImagePreview.innerHTML = `<img src="${url}" alt="Miniatura de promoción" class="w-full h-full object-cover rounded-lg">`;
            } else {
                promotionImagePreview.innerHTML = `<i data-lucide="image" class="w-12 h-12 text-gray-500"></i>`;
            }
            lucide.createIcons({ container: promotionImagePreview });
        });
    }

    // Listener para el botón "Agregar Promoción"
    if (addPromotionBtn) {
        addPromotionBtn.addEventListener('click', () => {
            openPanel('addPromotionPanel');
        });
    }
    
    // Renderiza todos los íconos de Lucide estáticos al final de la carga del DOM
    lucide.createIcons();
});
</script>
</body>
</html>