<?php include 'files/guardiankey.php'; ?>
<?php
ob_start();
session_start();

ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/../logs/php_errors.log');
error_reporting(E_ALL);

include_once 'db/db_connection.php';

$db_clients = [];
$db_leads = [];
$db_unique_appointments = [];
$db_recurring_appointments = [];

// Establecer valores por defecto (website_config fue eliminada)
$db_config = ['company_name' => 'Tu Negocio', 'contact_name' => 'Tu Nombre'];
$db_error_message = null;

// --- NUEVAS VARIABLES DE CONFIGURACIÓN ---
$db_schedule_config = ['slot_duration' => 60, 'capacity' => 1];
$db_weekly_hours = [];
$db_blocked_dates = [];
// --- FIN NUEVAS VARIABLES ---

try {
    // 1. Cargar nombre de la empresa/contacto (Asumiendo que se moverá a business_info o se deja fijo)
    
    // Carga de Business Info para Company Name y Contact Name
    $stmt_business_info = $pdo->query("SELECT full_name, company_name FROM business_info WHERE id = 1 LIMIT 1");
    if ($row = $stmt_business_info->fetch(PDO::FETCH_ASSOC)) {
        $db_config['company_name'] = $row['company_name'];
        $db_config['contact_name'] = $row['full_name'];
    }

    $stmt_clients = $pdo->query("SELECT id, first_name, last_name, email, phone, mobile, street_address, city, state_province, zip_code, CONCAT(first_name, ' ', last_name) AS full_name FROM clients");
    while ($row = $stmt_clients->fetch(PDO::FETCH_ASSOC)) {
        $db_clients['client-' . $row['id']] = [
            'id' => $row['id'],
            'first_name' => $row['first_name'],
            'last_name' => $row['last_name'],
            'name' => $row['full_name'],
            'email' => $row['email'],
            'phone' => $row['phone'],
            'mobile_phone' => $row['mobile'],
            'street_address' => $row['street_address'],
            'city' => $row['city'],
            'state_province' => $row['state_province'],
            'zip_code' => $row['zip_code']
        ];
    }

    $stmt_leads = $pdo->query("SELECT id, first_name, last_name, company, email, phone, mobile, CONCAT(first_name, ' ', last_name) AS full_name FROM leads");
    while ($row = $stmt_leads->fetch(PDO::FETCH_ASSOC)) {
        $db_leads['lead-' . $row['id']] = [
            'id' => $row['id'],
            'first_name' => $row['first_name'],
            'last_name' => $row['last_name'],
            'company' => $row['company'],
            'name' => $row['full_name'],
            'email' => $row['email'],
            'phone' => $row['phone'],
            'mobile_phone' => $row['mobile']
        ];
    }

    $client_names_map = [];
    foreach ($db_clients as $key => $client_data) {
        $client_names_map[$client_data['id']] = $client_data['name'];
    }

    $lead_names_map = [];
    foreach ($db_leads as $key => $lead_data) {
        $lead_names_map[$lead_data['id']] = $lead_data['name'];
    }

    $stmt_unique_appointments = $pdo->query("SELECT id, client_id, lead_id, appointment_date, appointment_time, status, notes FROM unique_appointments");
    while ($row = $stmt_unique_appointments->fetch(PDO::FETCH_ASSOC)) {
        $row['type'] = 'unica';
        $associated_entity_name = 'N/A';
        $associated_entity_type = 'none';
        $associated_entity_id = null;

        if (!empty($row['client_id'])) {
            $associated_entity_name = $client_names_map[$row['client_id']] ?? 'Cliente Desconocido';
            $associated_entity_type = 'client';
            $associated_entity_id = $row['client_id'];
        } elseif (!empty($row['lead_id'])) {
            $associated_entity_name = $lead_names_map[$row['lead_id']] ?? 'Prospecto Desconocido';
            $associated_entity_type = 'lead';
            $associated_entity_id = $row['lead_id'];
        }

        $row['associated_entity_name'] = $associated_entity_name;
        $row['associated_entity_type'] = $associated_entity_type;
        $row['associated_entity_id'] = $associated_entity_id;

        $db_unique_appointments['cita-unica-' . $row['id']] = $row;
    }

    $stmt_recurring_appointments = $pdo->query("SELECT id, client_id, lead_id, frequency, next_appointment_date, notes FROM recurring_appointments"); 
    $db_recurring_appointments = [];
    while ($row = $stmt_recurring_appointments->fetch(PDO::FETCH_ASSOC)) {
        $row['type'] = 'recurrente';
        $associated_entity_name = 'N/A';
        $associated_entity_type = 'none';
        $associated_entity_id = null;

        if (!empty($row['client_id'])) {
            $associated_entity_name = $client_names_map[$row['client_id']] ?? 'Cliente Desconocido';
            $associated_entity_type = 'client';
            $associated_entity_id = $row['client_id'];
        } elseif (!empty($row['lead_id'])) {
            $associated_entity_name = $lead_names_map[$row['lead_id']] ?? 'Prospecto Desconocido';
            $associated_entity_type = 'lead';
            $associated_entity_id = $row['lead_id'];
        }

        $row['associated_entity_name'] = $associated_entity_name;
        $row['associated_entity_type'] = $associated_entity_type;
        $row['associated_entity_id'] = $associated_entity_id;
        // No se asigna 'status' aquí, ya que su gestión en el frontend para recurrentes será diferente.

        $db_recurring_appointments['cita-recurrente-' . $row['id']] = $row;
    }

    // --- Carga de Configuración de Horario y Bloqueos (NUEVO) ---
    
    // schedule_config (Duración y Capacidad)
    $stmt_sched_config = $pdo->query("SELECT slot_duration, capacity FROM schedule_config WHERE id = 1 LIMIT 1");
    if ($row = $stmt_sched_config->fetch(PDO::FETCH_ASSOC)) {
        $db_schedule_config = $row;
        $db_schedule_config['slot_duration'] = (int)$db_schedule_config['slot_duration'];
        $db_schedule_config['capacity'] = (int)$db_schedule_config['capacity'];
    }

    // cms_weekly_hours (Horario Semanal)
    $stmt_weekly_hours = $pdo->query("SELECT day, is_open, open_time, close_time FROM cms_weekly_hours WHERE schedule_id = 1");
    while ($row = $stmt_weekly_hours->fetch(PDO::FETCH_ASSOC)) {
        $db_weekly_hours[$row['day']] = [
            'is_open' => (bool)$row['is_open'],
            'open_time' => $row['open_time'],
            'close_time' => $row['close_time']
        ];
    }
    
    // cms_blocked_dates (Fechas Bloqueadas)
    // NOTA: Se asume que la tabla cms_blocked_dates usa 'website_config_id' o 'id' para filtrar.
    $stmt_blocked_dates = $pdo->query("SELECT id, blocked_date FROM cms_blocked_dates");
    while ($row = $stmt_blocked_dates->fetch(PDO::FETCH_ASSOC)) {
        // Guardamos el objeto completo con ID para poder eliminarlo en JS
        $db_blocked_dates[] = $row; 
    }

} catch (PDOException $e) {
    $db_clients = [];
    $db_leads = [];
    $db_unique_appointments = [];
    $db_recurring_appointments = [];
    $db_schedule_config = ['slot_duration' => 60, 'capacity' => 1];
    $db_weekly_hours = [];
    $db_blocked_dates = [];
    $db_config = ['company_name' => 'Tu Negocio', 'contact_name' => 'Tu Nombre'];
    $db_error_message = 'Error al cargar datos iniciales de la base de datos: ' . $e->getMessage();
    error_log($db_error_message);
}

ob_end_clean();
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>Agenda De Actidades FlowCRM™ De OrozDesign Powered By OrozCO</title>
  <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">

    <?php include 'files/gtm-head.php'; ?>

    <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>
    <script src="https://unpkg.com/imask"></script>

    <link rel="stylesheet" href="style.css">
    <script src="files/header-manager.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

    <style>
       .stat-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.1);
        }
        
        .sidebar-ad-image {
            width: 100%;
            height: auto;
            border-radius: 0.5rem;
            cursor: pointer;
            transition: transform 0.2s ease-in-out;
        }
        .sidebar-ad-image:hover {
            transform: scale(1.02);
        }

        .calendar-day-header.today {
            background-color: var(--color-secondary);
            color: white;
            border: 2px solid var(--color-highlight);
        }
        .appointment-card {
            border-left: 4px solid var(--color-primary);
            display: block;
            width: 100%;
        }
        .appointment-card.cancelled {
            border-left-color: #9ca3af;
            background-color: #f3f4f6;
        }
        .appointment-card.cancelled p {
            text-decoration: line-through;
            color: #6b7280;
        }
        .appointment-card.completed {
            border-left-color: #10b981;
            background-color: #ecfdf5;
        }

        .appointment-list-item {
            border: 1px solid #e2e8f0;
            box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
            transition: all 0.2s ease-in-out;
        }
        .appointment-list-item:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        }

        .disabled-edit-btn, .disabled-delete-btn, .disabled-action-btn {
            opacity: 0.5;
            cursor: not-allowed;
            pointer-events: none;
        }
        .disabled-edit-btn:hover, .disabled-delete-btn:hover, .disabled-action-btn:hover {
            color: inherit !important;
            transform: none !important;
        }

        .calendar-day-clickable {
            cursor: pointer;
            transition: background-color 0.2s ease;
        }
        .calendar-day-clickable:hover {
            background-color: #f0f4f8;
        }

        .disabled-input, input:disabled, select:disabled, textarea:disabled {
            background-color: #f3f4f6 !important;
            cursor: not-allowed !important;
            border: 1px solid #d1d5db;
            color: #4b5563;
            font-weight: 600;
            box-shadow: inset 0 1px 2px rgba(0,0,0,0.06);
        }

        .disabled-button {
            opacity: 0.5;
            cursor: not-allowed !important;
            pointer-events: none;
        }

        .autocomplete-suggestion {
            padding: 0.75rem 1rem;
            cursor: pointer;
            border-bottom: 1px solid #f0f4f8;
            font-size: 0.875rem;
            color: #4a5568;
        }

        .autocomplete-suggestion:hover {
            background-color: #e2e8f0;
            color: #1a202c;
        }
        .autocomplete-suggestion:last-child {
            border-bottom: none;
        }
        .styled-readonly-input {
            background-color: #e9e9ed;
            cursor: not-allowed;
            border: 1px solid #d1d5db;
            color: #4b5563;
            font-weight: 600;
            box-shadow: inset 0 1px 2px rgba(0,0,0,0.06);
        }
        
        .px-2.py-1.bg-orange-100 {
            background-color: #ffedd5;
            color: #ea580c;
        }
        /* REGLAS PARA APILAMIENTO DE TABLAS RESPONSIVAS (agenda.php) */
        @media (max-width: 767px) {
            .responsive-invoices-table {
                border-collapse: separate;
            }
            .responsive-invoices-table thead {
                display: none;
            }
            .responsive-invoices-table,
            .responsive-invoices-table tbody,
            .responsive-invoices-table tr {
                display: block;
                width: 100%;
            }
            .responsive-invoices-table tr {
                margin-bottom: 1rem;
                border: 1px solid #e2e8f0;
                border-radius: 0.5rem;
                padding: 0.5rem;
                background-color: white;
                box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
            }
            .responsive-invoices-table td {
                display: flex;
                justify-content: space-between;
                align-items: center;
                text-align: right !important;
                padding: 0.75rem 1rem;
                position: relative;
                border-bottom: 1px solid #edf2f7;
                white-space: normal;
                word-break: break-word;
            }
            .responsive-invoices-table td:last-child {
                border-bottom: 0;
            }
            .responsive-invoices-table td::before {
                content: attr(data-label);
                font-weight: bold;
                text-transform: uppercase;
                text-align: left;
                margin-right: 1rem;
                color: #4a5568;
                flex-shrink: 0;
                white-space: normal;
            }
            .responsive-invoices-table td.actions-cell {
                text-align: center !important;
                padding-left: 1rem !important;
                justify-content: center;
            }
            .responsive-invoices-table td.actions-cell::before {
                content: none;
            }

            /* --- MODIFICACIÓN PARA VISTA SEMANAL EN MÓVILES (CITAS DE 2 EN 2) --- */
            /* Aplica estas reglas solo cuando la vista es semanal y el tamaño de pantalla es pequeño */
            #calendar-grid.weekly-mobile-grid {
                grid-template-columns: repeat(2, minmax(0, 1fr)); /* Cambia a 2 columnas en móvil */
            }
            
            #calendar-grid.weekly-mobile-grid .appointment-list-day {
                display: grid;
                grid-template-columns: repeat(1, minmax(0, 1fr)); /* 1 columna para las citas dentro del día */
                gap: 0.5rem; /* Espacio entre las tarjetas de cita */
                overflow-y: auto; /* Mantener scroll si hay muchas citas */
                max-height: 90px; /* Limitar altura para que no crezca demasiado */
            }

            #calendar-grid.weekly-mobile-grid .appointment-list-day .appointment-card {
                /* Ajustes para que las tarjetas de cita quepan bien en 2 columnas */
                flex-shrink: 0; /* No permitir que se encojan */
                min-width: 0; /* Permitir que el contenido se ajuste */
            }
        }
    </style>
</head>
<body data-page-title="Centro De Citas Agendadas De Servicios"
      data-page-subtitle="Administrador De Calendario De Citas Y Servicios Programados"
      data-page-icon="calendar-check">
    
    <div id="toast-container" class="toast-container"></div>
        
<?php include 'files/gtm-body.php'; ?>

<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>
    <div id="task-panel-overlay" class="off-canvas-overlay"></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="agenda" 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="calendar-days" class="w-7 h-7 text-[var(--color-primary)]"></i> CALENDARIO DE SERVICIOS Y EVENTOS
                            </h3>
                            <p class="text-gray-500 text-sm mt-1 uppercase">ORGANIZA Y MONITOREA TUS PRÓXIMAS PROGRAMACIONES.</p>
                        </div>
                        <div class="flex flex-col sm:flex-row items-center gap-4 w-full md:w-auto">
    <button id="config-panel-open-btn" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg flex items-center w-full sm:w-auto justify-center uppercase">
        <i data-lucide="settings" class="w-5 h-5 mr-2"></i> CONFIGURACIÓN
    </button>
    <button class="btn-secondary font-bold py-2 px-4 rounded-lg flex items-center w-full sm:w-auto justify-center uppercase" onclick="openPanel('agendarServicioPanel')">
        <i data-lucide="plus" class="w-5 h-5 mr-2"></i> AGENDAR CITA
    </button>
    <div class="relative inline-block text-left w-full sm:w-auto">
        <button type="button" id="download-citas-btn" class="btn-primary font-bold py-2 px-4 rounded-lg flex items-center w-full sm:w-auto justify-center uppercase">
            <i data-lucide="download" class="w-5 h-5 mr-2"></i> EXPORTAR
        </button>
        <div id="download-dropdown" class="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none hidden" role="menu" aria-orientation="vertical" aria-labelledby="download-citas-btn">
            <div class="py-1" role="none">
                <button class="text-gray-700 block w-full text-left px-4 py-2 text-sm hover:bg-gray-100" role="menuitem" id="export-csv">CSV (Google Calendar)</button>
                <button class="text-gray-700 block w-full text-left px-4 py-2 text-sm hover:bg-gray-100" role="menuitem" id="export-ical">iCalendar (.ics)</button>
            </div>
        </div>
    </div>
</div>
                    </div>

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 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-highlight)]">
        <i data-lucide="calendar-check" class="w-12 h-12 text-gray-700"></i>
        <div>
            <h3 class="text-lg font-extrabold text-gray-500 mb-1">TOTAL DEL MES</h3>
            <p id="monthly-total" class="text-5xl font-bold text-[var(--color-secondary)]">0</p>
            <p class="text-sm text-gray-400 mt-1">CITAS</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="calendar-plus" class="w-12 h-12 text-gray-700"></i>
        <div>
            <h3 class="text-lg font-extrabold text-gray-500 mb-1">NUEVAS</h3>
            <p id="monthly-new" class="text-5xl font-bold text-[var(--color-secondary)]">0</p>
            <p class="text-sm text-gray-400 mt-1">CITAS</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="repeat" class="w-12 h-12 text-gray-700"></i>
    <div>
        <h3 class="text-lg font-extrabold text-gray-500 mb-1">RECURRENTES</h3>
        <p id="monthly-recurring" class="text-5xl font-bold text-[var(--color-secondary)]">0</p>
        <p class="text-sm text-gray-400 mt-1">CITAS</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="calendar-x" class="w-12 h-12 text-gray-700"></i>
        <div>
            <h3 class="text-lg font-extrabold text-gray-500 mb-1">CANCELADAS</h3>
            <p id="monthly-cancelled" class="text-5xl font-bold text-[var(--color-secondary)]">0</p>
            <p class="text-sm text-gray-400 mt-1">CITAS</p>
        </div>
    </div>
</div>

                    <div class="mb-8 p-4 border border-gray-200 rounded-lg shadow-sm bg-gray-50">
                        <div class="flex justify-between items-center mb-4">
                            <button id="prev-btn" class="p-2 rounded-md hover:bg-gray-200"><i data-lucide="chevron-left"></i></button>
                            <h4 id="period-title" class="text-3xl font-extrabold text-gray-700 uppercase px-4 py-2"></h4>
                            <button id="next-btn" class="p-2 rounded-md hover:bg-gray-200"><i data-lucide="chevron-right"></i></button>
                        </div>
                        <div class="flex justify-center items-center gap-2 mb-4">
                            <button id="view-weekly-btn">Semanal</button>
                            <button id="view-monthly-btn">Mensual</button>
                        </div>
                        <div id="calendar-grid" class="grid grid-cols-1 md:grid-cols-7 gap-px bg-gray-200 border border-gray-200 rounded-lg overflow-hidden">
                        </div>
                    </div>

                    <div>
                        <h4 class="text-xl font-extrabold text-gray-700 mb-4 uppercase flex items-center gap-2">
                            <i data-lucide="calendar-days" class="w-6 h-6 text-[var(--color-primary)]"></i> PRÓXIMAS CITAS DE LA SEMANA
                        </h4>
                        <div class="flex flex-col md:flex-row gap-4 mb-4">
                            <div class="relative flex-grow">
                                <input type="text" id="appointment-search" placeholder="Buscar Por Cliente" 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>
                            <select id="appointment-filter-status" class="w-full md:w-48 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                                <optgroup label="FILTRAR POR FECHA">
                                    <option value="all">TODAS</option> <option value="hoy">HOY</option>
                                    <option value="proximas" selected>PRÓXIMAS</option>
                                    <option value="pasadas">PASADAS</option>
                                </optgroup>
                                <optgroup label="FILTRAR POR ESTADO">
                                    <option value="todas">TODAS</option>
                                    <option value="pending">PENDIENTE</option>
                                    <option value="confirmed">CONFIRMADA</option>
                                    <option value="completed">COMPLETADA</option>
                                    <option value="cancelled">CANCELADA</option>
                                </optgroup>
                            </select>
                            <select id="appointment-filter-type" class="w-full md:w-48 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                                <option value="all">TODOS LOS TIPOS</option>
                                <option value="unica">ÚNICA</option>
                                <option value="recurrente">RECURRENTE</option>
                            </select>
                        </div>
                        <div id="appointment-list" class="space-y-3">
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </main>
</div>

<div id="configPanel" class="fixed inset-y-0 right-0 w-full md:w-1/3 bg-white shadow-lg transform translate-x-full transition-transform duration-300 ease-in-out z-50 overflow-y-auto">
    <div class="flex flex-col h-full">
        <div class="bg-slate-800 text-white p-6 flex justify-between items-center flex-shrink-0">
            <div class="flex items-center">
                <i data-lucide="settings" class="w-6 h-6 mr-3 text-[var(--color-highlight)]"></i>
                <h3 class="text-xl font-bold uppercase">CONFIGURACIÓN DE AGENDA</h3>
            </div>
            <button onclick="closePanel('configPanel')" class="text-gray-400 hover:text-gray-200"><i data-lucide="x" class="w-6 h-6"></i></button>
        </div>
        <div class="p-8 flex-grow flex flex-col space-y-8 overflow-y-auto pr-2 -mr-2">

            <div class="border border-gray-200 p-4 rounded-lg bg-gray-50">
                <h4 class="text-lg font-bold text-gray-800 mb-4 uppercase flex items-center gap-2"><i data-lucide="clock" class="w-5 h-5 text-[var(--color-primary)]"></i> Intervalo y Capacidad</h4>
                <form id="config-capacity-form" class="space-y-4">
                    <div>
                        <label for="config-slot-duration" class="block text-gray-700 text-sm font-bold mb-2 uppercase">DURACIÓN DEL ESPACIO (Minutos)</label>
                        <select id="config-slot-duration" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                            <option value="15">15 Minutos</option>
                            <option value="30">30 Minutos</option>
                            <option value="60">60 Minutos (1 Hora)</option>
                            <option value="90">90 Minutos (1.5 Horas)</option>
                            <option value="120">120 Minutos (2 Horas)</option>
                        </select>
                        <p class="text-xs text-gray-500 mt-1">Define el bloque de tiempo que ocupa una sola cita.</p>
                    </div>
                    <div>
                        <label for="config-capacity" class="block text-gray-700 text-sm font-bold mb-2 uppercase">CAPACIDAD SIMULTÁNEA</label>
                        <input type="number" id="config-capacity" min="1" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                        <p class="text-xs text-gray-500 mt-1">Máximo de citas que puedes agendar al mismo tiempo.</p>
                    </div>
                    <div class="flex justify-end">
                        <button type="submit" id="save-capacity-btn" class="btn-primary font-bold py-2 px-4 rounded-lg uppercase">GUARDAR CAPACIDAD</button>
                    </div>
                </form>
            </div>

            <div class="border border-gray-200 p-4 rounded-lg bg-gray-50">
                <h4 class="text-lg font-bold text-gray-800 mb-4 uppercase flex items-center gap-2"><i data-lucide="calendar" class="w-5 h-5 text-[var(--color-primary)]"></i> Horario Semanal</h4>
                <form id="config-weekly-hours-form" class="space-y-4">
                    <div id="weekly-hours-list" class="space-y-3">
                        </div>
                    <div class="flex justify-end">
                        <button type="submit" id="save-weekly-hours-btn" class="btn-primary font-bold py-2 px-4 rounded-lg uppercase">GUARDAR HORARIO</button>
                    </div>
                </form>
            </div>

            <div class="border border-gray-200 p-4 rounded-lg bg-gray-50">
                <h4 class="text-lg font-bold text-gray-800 mb-4 uppercase flex items-center gap-2"><i data-lucide="calendar-off" class="w-5 h-5 text-[var(--color-secondary)]"></i> Días No Laborables</h4>
                <form id="config-blocked-dates-form" class="space-y-4">
                    <div class="flex gap-4 items-end">
                        <div class="flex-grow">
                            <label for="config-block-date" class="block text-gray-700 text-sm font-bold mb-2 uppercase">SELECCIONAR FECHA A BLOQUEAR</label>
                            <input type="date" id="config-block-date" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                        </div>
                        <button type="button" id="add-blocked-date-btn" class="btn-secondary font-bold py-3 px-4 rounded-lg uppercase flex-shrink-0">BLOQUEAR</button>
                    </div>

                    <div id="blocked-dates-list" class="space-y-2 mt-4 max-h-40 overflow-y-auto">
                        </div>
                </form>
            </div>

        </div>
    </div>
</div>

<div id="agendarServicioPanel" class="fixed inset-y-0 right-0 w-full md:w-1/3 bg-white shadow-lg transform translate-x-full transition-transform duration-300 ease-in-out z-50 overflow-y-auto">
    <div class="flex flex-col h-full">
        <div class="bg-slate-800 text-white p-6 flex justify-between items-center flex-shrink-0">
            <div class="flex items-center">
                <i data-lucide="calendar-plus" class="w-6 h-6 mr-3 text-[var(--color-highlight)]"></i>
                <h3 class="text-xl font-bold uppercase">AGENDAR NUEVA CITA</h3>
            </div>
            <button onclick="closePanel('agendarServicioPanel')" class="text-gray-400 hover:text-gray-200"><i data-lucide="x" class="w-6 h-6"></i></button>
        </div>
        <div class="p-8 flex-grow flex flex-col">
            <form id="agendar-servicio-form" class="flex-grow overflow-y-auto pr-2 -mr-2">
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div class="mb-4 md:mb-0 relative">
                        <label for="cita-cliente-display" class="block text-gray-700 text-sm font-bold mb-2 uppercase">CLIENTE</label>
                        <input type="text" id="cita-cliente-display" placeholder="Buscar Cliente..."
                               class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                        <input type="hidden" id="cita-cliente"> <div id="cita-cliente-suggestions" class="absolute z-10 w-full bg-white border border-gray-300 rounded-lg shadow-lg mt-1 max-h-48 overflow-y-auto hidden"></div>
                        <p id="cita-cliente-info" class="text-xs text-gray-500 mt-1"></p>
                    </div>

                    <div class="mb-4 md:mb-0 relative">
                        <label for="cita-prospecto-display" class="block text-gray-700 text-sm font-bold mb-2 uppercase">PROSPECTO</label>
                        <input type="text" id="cita-prospecto-display" placeholder="Buscar Prospecto..."
                               class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                        <input type="hidden" id="cita-prospecto"> <div id="cita-prospecto-suggestions" class="absolute z-10 w-full bg-white border border-gray-300 rounded-lg shadow-lg mt-1 max-h-48 overflow-y-auto hidden"></div>
                        <p id="cita-prospecto-info-adicional" class="text-xs text-gray-500 mt-1"></p>
                    </div>

                    <div class="mb-4 md:mb-0">
                        <label for="cita-fecha" class="block text-gray-700 text-sm font-bold mb-2 uppercase">FECHA</label>
                        <input type="date" id="cita-fecha" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                    </div>
                    <div class="mb-4 md:mb-0 flex space-x-2">
                        <div class="w-1/2">
                            <label for="cita-hora-select" class="block text-gray-700 text-sm font-bold mb-2 uppercase">HORA</label>
                            <select id="cita-hora-select" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white"></select>
                        </div>
                        <div class="w-1/2">
                            <label for="cita-minuto-select" class="block text-gray-700 text-sm font-bold mb-2 uppercase">MINUTO</label>
                            <select id="cita-minuto-select" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white"></select>
                        </div>
                    </div>
                </div>

                <div class="mt-6 mb-4">
                    <label class="inline-flex items-center">
                        <input type="checkbox" id="cita-recurrente-checkbox" class="form-checkbox h-5 w-5 text-[var(--color-primary)] rounded focus:ring-[var(--color-highlight)]">
                        <span class="ml-2 text-gray-700 font-bold uppercase text-sm">CITA RECURRENTE</span>
                    </label>
                </div>

                <div id="recurrencia-options" class="grid grid-cols-1 md:grid-cols-2 gap-4 hidden">
                    <div>
                        <label for="cita-frecuencia" class="block text-gray-700 text-sm font-bold mb-2 uppercase">FRECUENCIA</label>
                        <select id="cita-frecuencia" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                            <option value="weekly">SEMANAL</option>
                            <option value="bi-weekly">QUINCENAL</option>
                            <option value="monthly">MENSUAL</option>
                        </select>
                    </div>
                    <div>
                        <label for="cita-proxima-cita-display" class="block text-gray-700 text-sm font-bold mb-2 uppercase">TU PRÓXIMA CITA SERÁ:</label>
                        <input type="text" id="cita-proxima-cita-display" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] styled-readonly-input" readonly>
                        <input type="hidden" id="cita-proxima-cita"> </div>
                </div>

                <div class="mt-6">
                    <label for="cita-notas" class="block text-gray-700 text-sm font-bold mb-2 uppercase">NOTAS (OPCIONAL)</label>
                    <textarea id="cita-notas" rows="3" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="Detalles Adicionales..."></textarea>
                </div>

                <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('agendarServicioPanel')">CANCELAR</button>
                    <button type="submit" class="btn-secondary font-bold py-2 px-4 rounded-lg uppercase">AGENDAR CITA</button>
                </div>
            </form>
        </div>
    </div>
</div>

<div id="viewCitaPanel" class="fixed inset-y-0 right-0 w-full md:w-1/3 bg-white shadow-lg transform translate-x-full transition-transform duration-300 ease-in-out z-50 overflow-y-auto">
    <div class="flex flex-col h-full">
        <div class="bg-slate-800 text-white p-6 flex justify-between items-center flex-shrink-0">
            <div class="flex items-center">
                <i data-lucide="calendar-check" class="w-6 h-6 mr-3 text-[var(--color-highlight)]"></i>
                <h3 class="text-xl font-bold uppercase">DETALLE DE CITA</h3>
            </div>
            <button onclick="closePanel('viewCitaPanel')" class="text-gray-400 hover:text-gray-200"><i data-lucide="x" class="w-6 h-6"></i></button>
        </div>
        <div class="p-8 flex-grow flex flex-col">
            <form id="view-cita-form" class="flex-grow overflow-y-auto pr-2 -mr-2">
                <input type="hidden" id="view-cita-id">
                <input type="hidden" id="view-cita-type">
                <input type="hidden" id="view-cita-original-status">
                <div class="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-4">
                    <div>
                        <label for="view-cita-cliente" class="block text-gray-700 text-sm font-bold mb-2 uppercase">CLIENTE</label>
                        <input type="text" id="view-cita-cliente" 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 cliente" disabled>
                        <p id="view-cita-cliente-info" class="text-xs text-gray-500 mt-1"></p>
                    </div>
                    <div>
                        <label for="view-cita-prospecto" class="block text-gray-700 text-sm font-bold mb-2 uppercase">PROSPECTO</label>
                        <input type="text" id="view-cita-prospecto" 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 prospecto" disabled>
                        <p id="view-cita-prospecto-info-adicional" class="text-xs text-gray-500 mt-1"></p>
                    </div>
                    <div id="view-cita-fecha-group">
                        <label for="view-cita-fecha" class="block text-gray-700 text-sm font-bold mb-2 uppercase">FECHA</label>
                        <input type="date" id="view-cita-fecha" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                    </div>
                    <div id="view-cita-hora-group" class="flex space-x-2"> <div class="w-1/2">
                            <label for="view-cita-hora-select" class="block text-gray-700 text-sm font-bold mb-2 uppercase">HORA</label>
                            <select id="view-cita-hora-select" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white"></select>
                        </div>
                        <div class="w-1/2">
                            <label for="view-cita-minuto-select" class="block text-gray-700 text-sm font-bold mb-2 uppercase">MINUTO</label>
                            <select id="view-cita-minuto-select" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white"></select>
                        </div>
                    </div>
                    <div id="view-cita-frecuencia-group" class="hidden">
                        <label for="view-cita-frecuencia" class="block text-gray-700 text-sm font-bold mb-2 uppercase">FRECUENCIA</label>
                        <select id="view-cita-frecuencia" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white">
                            <option value="weekly">SEMANAL</option>
                            <option value="bi-weekly">QUINCENAL</option>
                            <option value="monthly">MENSUAL</option>
                        </select>
                    </div>
                    <div id="view-cita-proxima-cita-group" class="hidden">
                        <label for="view-cita-proxima-cita-display" class="block text-gray-700 text-sm font-bold mb-2 uppercase">PRÓXIMA CITA</label>
                        <input type="text" id="view-cita-proxima-cita-display" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] styled-readonly-input" readonly>
                        <input type="hidden" id="view-cita-proxima-cita"> </div>
                </div>
                <div class="mt-6 mb-4 md:col-span-2">
                    <label for="view-cita-notas" class="block text-gray-700 text-sm font-bold mb-2 uppercase">NOTAS (OPCIONAL)</label>
                    <textarea id="view-cita-notas" rows="3" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]" placeholder="Detalles adicionales de la cita..."></textarea>
                </div>
                <div class="md:col-span-2 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('viewCitaPanel')">CANCELAR</button>
                    <button type="submit" class="btn-primary font-bold py-2 px-4 rounded-lg uppercase" id="save-cita-changes-btn">GUARDAR CAMBIOS</button>
                </div>
            </form>
        </div>
    </div>
</div>

<div id="messageCitaPanel" class="fixed inset-y-0 right-0 w-full md:w-1/3 bg-white shadow-lg transform translate-x-full transition-transform duration-300 ease-in-out z-50 overflow-y-auto">
    <div class="flex flex-col h-full">
        <div class="bg-slate-800 text-white p-6 flex justify-between items-center flex-shrink-0">
            <div class="flex items-center">
                <i data-lucide="send" class="w-6 h-6 mr-3 text-[var(--color-highlight)]"></i>
                <h3 class="text-xl font-bold uppercase">MENSAJE DE CONFIRMACIÓN</h3>
            </div>
            <button onclick="closePanel('messageCitaPanel')" class="text-gray-400 hover:text-gray-200"><i data-lucide="x" class="w-6 h-6"></i></button>
        </div>
        <div class="p-8 flex-grow flex flex-col">
            <div class="flex-grow overflow-y-auto pr-2 -mr-2 space-y-6">
                <p class="text-sm text-gray-600 mb-4">Genera Mensajes De Confirmación Para Tu Cliente y Envíalos Fácilmente Por WhatsApp</p>

                <div class="border border-gray-200 rounded-lg p-4 bg-gray-50">
                    <h4 class="text-lg font-bold text-gray-800 mb-2">Detalles De La Cita:</h4>
                    <p class="text-sm text-gray-700"><strong>Cliente:</strong> <span id="msg-cita-cliente"></span></p>
                    <p class="text-sm text-gray-700"><strong>Prospecto:</strong> <span id="msg-cita-prospecto"></span></p>
                    <p class="text-sm text-gray-700"><strong>Fecha:</strong> <span id="msg-cita-fecha"></span></p>
                    <p class="text-sm text-gray-700"><strong>Hora:</strong> <span id="msg-cita-hora"></span></p>
                    <p class="text-sm text-gray-700"><strong>Tipo:</strong> <span id="msg-cita-tipo"></span></p>
                    <p class="text-sm text-gray-700"><strong>Teléfono:</strong> <span id="msg-cita-telefono"></span></p>
                </div>

                <div class="space-y-4">
                    <h4 class="text-xl font-bold text-[var(--color-primary)] uppercase">Mensaje en Español</h4>
                    <textarea id="message-spanish" rows="6" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] font-mono text-sm"></textarea>
                    <div class="flex justify-end gap-2">
                        <button type="button" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase text-sm flex items-center copy-message-btn" data-lang="es">
                            <i data-lucide="copy" class="w-4 h-4 mr-2"></i> COPIAR MENSAJE
                        </button>
                        <button type="button" class="btn-primary font-bold py-2 px-4 rounded-lg uppercase text-sm flex items-center send-whatsapp-btn" data-lang="es">
                            <i data-lucide="message-circle" class="w-4 h-4 mr-2"></i> ENVIAR POR WHATSAPP
                        </button>
                    </div>
                </div>

                <hr class="border-gray-200">

                <div class="space-y-4">
                    <h4 class="text-xl font-bold text-[var(--color-primary)] uppercase">Mensaje en Inglés</h4>
                    <textarea id="message-english" rows="6" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] font-mono text-sm"></textarea>
                    <div class="flex justify-end gap-2">
                        <button type="button" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase text-sm flex items-center copy-message-btn" data-lang="es">
                            <i data-lucide="copy" class="w-4 h-4 mr-2"></i> COPIAR MENSAJE
                        </button>
                        <button type="button" class="btn-primary font-bold py-2 px-4 rounded-lg uppercase text-sm flex items-center send-whatsapp-btn" data-lang="en">
                            <i data-lucide="message-circle" class="w-4 h-4 mr-2"></i> ENVIAR POR WHATSAPP
                        </button>
                    </div>
                </div>
            </div>
        </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-[var(--color-secondary)]"></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="window.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>

<script>
    document.addEventListener('DOMContentLoaded', function() {
        let currentDate = new Date(); // Fecha de referencia para el calendario
        let currentView = 'weekly'; // 'weekly' o 'monthly'

        // Variables que recibirán los datos inyectados por PHP
        let dbClients = {};
        let dbLeads = {};
        let dbCitasUnicas = {};
        let dbCitasRecurrentes = {};
        let dbErrorMessage = null;
        let appSettings = {
            companyName: 'Tu Negocio',
            contactName: 'Tu Nombre'
        };
        // Variables globales de configuración inicializadas con los valores de PHP
        let dbScheduleConfig = {
            slot_duration: <?php echo json_encode($db_schedule_config['slot_duration'] ?? 60); ?>,
            capacity: <?php echo json_encode($db_schedule_config['capacity'] ?? 1); ?>
        };
        // CRÍTICO: dbWeeklyHours necesita que el JS sepa si está abierto (is_open) y las horas
        let dbWeeklyHours = <?php echo json_encode($db_weekly_hours); ?>;
        // CRÍTICO: dbBlockedDates es un array de objetos con ID y fecha
        let dbBlockedDates = <?php echo json_encode($db_blocked_dates); ?>; 
        
        // INYECCIÓN DE DATOS DESDE PHP
        <?php if (isset($db_clients)): ?>
            dbClients = <?php echo json_encode($db_clients); ?>;
            dbLeads = <?php echo json_encode($db_leads); ?>;
            dbCitasUnicas = <?php echo json_encode($db_unique_appointments); ?>;
            dbCitasRecurrentes = <?php echo json_encode($db_recurring_appointments); ?>;
            appSettings.companyName = "<?php echo addslashes($db_config['company_name']); ?>";
            appSettings.contactName = "<?php echo addslashes($db_config['contact_name']); ?>";

            <?php if ($db_error_message): ?>
                showToast("Error cargando datos iniciales de la DB: <?php echo addslashes($db_error_message); ?>", 'error');
            <?php endif; ?>
        <?php else: ?>
            showToast("No se pudieron cargar los datos iniciales de la agenda. Revise la configuración del servidor o si las tablas están vacías.", 'error');
            dbErrorMessage = "No se pudieron cargar los datos iniciales de la agenda. Revise la configuración del servidor o si las tablas están vacías.";
        <?php endif; ?>
        
        // Elementos del DOM
        const mobileMenuButton = document.getElementById('mobile-menu-button');
        const sidebar = document.getElementById('sidebar'); 
        const sidebarOverlay = document.getElementById('sidebar-overlay');
        const prevBtn = document.getElementById('prev-btn');
        const nextBtn = document.getElementById('next-btn');
        const periodTitle = document.getElementById('period-title');
        const viewWeeklyBtn = document.getElementById('view-weekly-btn');
        const viewMonthlyBtn = document.getElementById('view-monthly-btn');
        const agendarServicioForm = document.getElementById('agendar-servicio-form');
        const viewCitaForm = document.getElementById('view-cita-form');
        const confirmDeleteButton = document.getElementById('confirm-delete-button');
        const confirmItemTypeSpan = document.getElementById('confirm-item-type');
        const citaRecurrenteCheckbox = document.getElementById('cita-recurrente-checkbox');
        const recurrenciaOptionsDiv = document.getElementById('recurrencia-options');
        const citaFrecuenciaSelect = document.getElementById('cita-frecuencia');
        const citaFecha = document.getElementById('cita-fecha');
        const citaProximaCitaDisplay = document.getElementById('cita-proxima-cita-display');
        const citaProximaCitaInput = document.getElementById('cita-proxima-cita');
        const citaClienteDisplay = document.getElementById('cita-cliente-display');
        const citaClienteInput = document.getElementById('cita-cliente');
        const citaClienteSuggestions = document.getElementById('cita-cliente-suggestions');
        const citaClienteInfo = document.getElementById('cita-cliente-info');
        const citaProspectoDisplay = document.getElementById('cita-prospecto-display');
        const citaProspectoInput = document.getElementById('cita-prospecto');
        const citaProspectoSuggestions = document.getElementById('cita-prospecto-suggestions');
        const citaProspectoInfoAdicional = document.getElementById('cita-prospecto-info-adicional');
        const citaNotas = document.getElementById('cita-notas');
        const citaHoraSelect = document.getElementById('cita-hora-select');
        const citaMinutoSelect = document.getElementById('cita-minuto-select');
        const viewCitaId = document.getElementById('view-cita-id');
        const viewCitaType = document.getElementById('view-cita-type');
        const viewCitaOriginalStatus = document.getElementById('view-cita-original-status');
        const viewCitaCliente = document.getElementById('view-cita-cliente');    
        const viewCitaClienteInfo = document.getElementById('view-cita-cliente-info');
        const viewCitaProspecto = document.getElementById('view-cita-prospecto');
        const viewCitaProspectoInfoAdicional = document.getElementById('view-cita-prospecto-info-adicional');
        const viewCitaFecha = document.getElementById('view-cita-fecha');
        const viewCitaHoraSelect = document.getElementById('view-cita-hora-select');
        const viewCitaMinutoSelect = document.getElementById('view-cita-minuto-select');
        const viewCitaFrecuencia = document.getElementById('view-cita-frecuencia');
        const viewCitaProximaCitaDisplay = document.getElementById('view-cita-proxima-cita-display');
        const viewCitaProximaCita = document.getElementById('view-cita-proxima-cita');
        const viewCitaNotas = document.getElementById('view-cita-notas');
        const saveCitaChangesBtn = document.getElementById('save-cita-changes-btn');
        const viewCitaFechaGroup = document.getElementById('view-cita-fecha-group');
        const viewCitaHoraGroup = document.getElementById('view-cita-hora-group'); 
        const viewCitaFrecuenciaGroup = document.getElementById('view-cita-frecuencia-group');
        const viewCitaProximaCitaGroup = document.getElementById('view-cita-proxima-cita-group');
        const appointmentSearch = document.getElementById('appointment-search');
        const appointmentFilterStatus = document.getElementById('appointment-filter-status');
        const appointmentFilterType = document.getElementById('appointment-filter-type');
        const downloadCitasBtn = document.getElementById('download-citas-btn');
        const downloadDropdown = document.getElementById('download-dropdown');
        const exportCsvBtn = document.getElementById('export-csv');
        const exportIcalBtn = document.getElementById('export-ical');
        const panelOverlay = document.createElement('div');
        panelOverlay.id = 'panel-overlay';
        panelOverlay.className = 'fixed inset-0 bg-gray-900 bg-opacity-75 z-40 hidden';
        document.body.appendChild(panelOverlay);
        const messageCitaPanel = document.getElementById('messageCitaPanel');
        const msgCitaCliente = document.getElementById('msg-cita-cliente');
        const msgCitaProspecto = document.getElementById('msg-cita-prospecto');
        const msgCitaFecha = document.getElementById('msg-cita-fecha');
        const msgCitaHora = document.getElementById('msg-cita-hora');
        const msgCitaTipo = document.getElementById('msg-cita-tipo');
        const msgCitaTelefono = document.getElementById('msg-cita-telefono');
        const messageSpanish = document.getElementById('message-spanish');
        const messageEnglish = document.getElementById('message-english');
        const copyMessageBtns = document.querySelectorAll('.copy-message-btn');
        const sendWhatsappBtns = document.querySelectorAll('.send-whatsapp-btn');
        // Nuevas referencias al DOM para el panel de configuración
        const configPanel = document.getElementById('configPanel');
        const configCapacityForm = document.getElementById('config-capacity-form');
        const configSlotDuration = document.getElementById('config-slot-duration');
        const configCapacity = document.getElementById('config-capacity');
        const saveCapacityBtn = document.getElementById('save-capacity-btn');
        const weeklyHoursList = document.getElementById('weekly-hours-list');
        const addBlockedDateBtn = document.getElementById('add-blocked-date-btn');
        const configBlockDate = document.getElementById('config-block-date');
        const blockedDatesList = document.getElementById('blocked-dates-list');
        const configWeeklyHoursForm = document.getElementById('config-weekly-hours-form');
        const saveWeeklyHoursBtn = document.getElementById('save-weekly-hours-btn'); 
        const configPanelOpenBtn = document.getElementById('config-panel-open-btn');


        // --- Funciones para manejar el sidebar del menú hamburguesa ---
        if (mobileMenuButton && sidebar && sidebarOverlay) {
            mobileMenuButton.addEventListener('click', () => {
                sidebar.classList.toggle('-translate-x-full');
                sidebarOverlay.classList.toggle('hidden');
            });

            sidebarOverlay.addEventListener('click', () => {
                sidebar.classList.add('-translate-x-full');
                sidebarOverlay.classList.add('hidden');
            });
        }
        // --- FIN Funciones para manejar el sidebar del menú hamburguesa ---


// --- FUNCIONES CORE DE AGENDA (HORARIOS Y SLOTS) ---
        // Funcion que crea los slots disponibles
        function generateAvailableSlots(dateStr) {
            // 1. Determinar el día de la semana y si está bloqueado
            const selectedDate = new Date(dateStr + 'T00:00:00');
            // getDay() devuelve 0 para Domingo, 1 para Lunes, etc.
            const dayOfWeekIndex = selectedDate.getDay(); 
            const daysMap = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
            const dayName = daysMap[dayOfWeekIndex]; 

            // 2. Verificar si el día está en la lista de fechas bloqueadas
            const isDateBlocked = dbBlockedDates.some(item => item.blocked_date === dateStr); 

            // 3. Obtener la configuración del día y duración del slot
            const dayConfig = dbWeeklyHours[dayName];
            const slotDuration = dbScheduleConfig.slot_duration || 60; // 60 minutos por defecto

            let isAvailable = false;
            let openTimeStr = null;
            let closeTimeStr = null;

            if (dayConfig) {
                // Aseguramos que is_open sea true (no solo '1' o 'true')
                isAvailable = dayConfig.is_open === true; 
                openTimeStr = dayConfig.open_time;
                closeTimeStr = dayConfig.close_time;
            }
            
            // Si la fecha está bloqueada o no está disponible en la configuración
            if (isDateBlocked || !isAvailable || !openTimeStr || !closeTimeStr) {
                showToast(`El ${dayName} (${dateStr}) no está disponible.`, 'warning');
                return []; // Retorna lista vacía si no está disponible
            }

            // 4. Generar los slots
            const slots = [];
            // Usamos la fecha seleccionada para el contexto de hora (YYYY-MM-DDT)
            let currentTime = new Date(dateStr + 'T' + openTimeStr); 
            const endTime = new Date(dateStr + 'T' + closeTimeStr);   
            
            // Si la fecha seleccionada es HOY, ajustar la hora de inicio al futuro
            const now = new Date();
            const isToday = selectedDate.toDateString() === now.toDateString();
            
            if (isToday) {
                // Ajustar el tiempo actual al múltiplo superior del slotDuration
                const currentMinutes = now.getHours() * 60 + now.getMinutes();
                // Calcula el inicio del siguiente slot
                let nextSlotMinutes = Math.ceil(currentMinutes / slotDuration) * slotDuration;

                const nextSlotHour = Math.floor(nextSlotMinutes / 60);
                const nextSlotMinute = nextSlotMinutes % 60;

                // Crear el punto de inicio ajustado para HOY
                let todayStartTime = new Date(dateStr + 'T00:00:00');
                todayStartTime.setHours(nextSlotHour, nextSlotMinute, 0);

                // Si el tiempo ajustado es posterior a la hora de cierre, no hay más slots hoy
                if (todayStartTime.getTime() >= endTime.getTime()) {
                     return [];
                }
                
                // Si el tiempo ajustado es anterior a la hora de apertura definida (ej. estás ajustando a las 8:00 pero abre a las 9:00)
                if (todayStartTime.getTime() < currentTime.getTime()) {
                    // Usamos la hora de apertura definida si ya pasó la hora actual
                    currentTime = new Date(dateStr + 'T' + openTimeStr); 
                } else {
                    // Usamos el tiempo ajustado si es posterior a la hora actual y posterior a la hora de apertura
                    currentTime = todayStartTime;
                }
            }
            
            // Generar slots hasta la hora de cierre
            while (currentTime.getTime() < endTime.getTime()) {
                const hour = String(currentTime.getHours()).padStart(2, '0');
                const minute = String(currentTime.getMinutes()).padStart(2, '0');
                slots.push({ hour, minute });
                
                // Avanzar al siguiente slot
                currentTime.setTime(currentTime.getTime() + slotDuration * 60 * 1000);
            }

            return slots;
        }

        // Modificar la función populateTimeSelect existente
        function populateTimeSelect(selectElement, type, slots, selectedHour = null, selectedMinute = null) {
            selectElement.innerHTML = '';
            
            // Si no hay slots disponibles, mostramos una opción vacía
            if (!slots || slots.length === 0) {
                const option = document.createElement('option');
                option.value = '';
                option.textContent = (type === 'hour') ? '🚫 Cerrado o Lleno' : 'N/A';
                selectElement.appendChild(option);
                return;
            }

            if (type === 'hour') {
                const uniqueHours = [...new Set(slots.map(s => s.hour))].sort();
                
                uniqueHours.forEach(hour => {
                    const option = document.createElement('option');
                    option.value = hour;
                    option.textContent = hour;
                    if (hour === selectedHour) {
                        option.selected = true;
                    }
                    selectElement.appendChild(option);
                });
                
            } else if (type === 'minute') {
                const currentSelectedHour = document.getElementById('cita-hora-select').value || selectedHour;

                if (!currentSelectedHour) return;

                const filteredMinutes = slots
                    .filter(s => s.hour === currentSelectedHour)
                    .map(s => s.minute);

                [...new Set(filteredMinutes)].sort().forEach(minute => {
                    const option = document.createElement('option');
                    option.value = minute;
                    option.textContent = minute;
                    if (minute === selectedMinute) {
                        option.selected = true;
                    }
                    selectElement.appendChild(option);
                });
            }
        }
        
        // Función que se ejecuta al cambiar la fecha, actualiza Hora y Minuto
        function updateTimeSlots(dateStr) {
            const slots = generateAvailableSlots(dateStr);

            // 1. Popular la hora
            populateTimeSelect(citaHoraSelect, 'hour', slots);
            
            // 2. Almacenar los slots disponibles en el DOM para referencia del minuto
            citaHoraSelect.dataset.slots = JSON.stringify(slots); 
            
            // 3. Actualizar los minutos al final, basado en la hora seleccionada por defecto (si hay)
            citaHoraSelect.dispatchEvent(new Event('change'));
            
            // Si no hay slots, deshabilitar los selectores
            const hasSlots = slots && slots.length > 0;
            toggleInputDisabledStyle(citaHoraSelect, !hasSlots);
            toggleInputDisabledStyle(citaMinutoSelect, !hasSlots);
        }

// --- FIN FUNCIONES CORE DE AGENDA ---


// --- FUNCIONES NUEVAS PARA CONFIG PANEL ---

        // Función corregida para alternar el estilo de input deshabilitado
        function toggleInputDisabledStyle(element, isDisabled) {
            element.disabled = isDisabled;
            if (isDisabled) {
                element.classList.add('disabled-input');
            } else {
                element.classList.remove('disabled-input');
            }
        }
        
        async function renderConfigPanel() {
            try {
                const response = await fetch('db/agenda-config-read.php');
                const result = await response.json();

                if (result.status === 'success') {
                    const data = result.data;
                    
                    dbScheduleConfig = data.schedule_config; 
                    dbWeeklyHours = data.weekly_hours;       
                    dbBlockedDates = data.blocked_dates;
                    
                    configSlotDuration.value = data.schedule_config.slot_duration;
                    configCapacity.value = data.schedule_config.capacity;

                    renderWeeklyHours();

                    renderBlockedDates(data.blocked_dates);
                } else {
                    showToast(`Error al cargar configuración: ${result.message}`, 'error');
                }
            } catch (error) {
                showToast("Error de conexión al cargar la configuración de agenda.", 'error');
            }
        }

        function renderWeeklyHours() {
            weeklyHoursList.innerHTML = '';
            const daysOrder = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
            const daysMap = { 'Monday': 'Lunes', 'Tuesday': 'Martes', 'Wednesday': 'Miércoles', 'Thursday': 'Jueves', 'Friday': 'Viernes', 'Saturday': 'Sábado', 'Sunday': 'Domingo' };

            daysOrder.forEach(dayKey => {
                // Usamos dbWeeklyHours que fue actualizado por la llamada READ
                const config = dbWeeklyHours[dayKey] || { is_open: false, open_time: '09:00', close_time: '17:00' };
                const dayEl = document.createElement('div');
                // Se agregó la clase 'weekly-hour-day' y data-day para el JS
                dayEl.className = 'flex flex-col sm:flex-row items-center justify-between p-3 border-b border-gray-100 weekly-hour-day';
                dayEl.dataset.day = dayKey; 
                
                // Asegurar formato HH:MM (slice es por seguridad si el valor viene de una constante 'HH:MM:SS')
                const openTimeDisplay = (config.open_time.length > 5 ? config.open_time.substring(0, 5) : config.open_time) || '09:00';
                const closeTimeDisplay = (config.close_time.length > 5 ? config.close_time.substring(0, 5) : config.close_time) || '17:00';

                dayEl.innerHTML = `
                    <div class="flex items-center w-full sm:w-1/4 mb-2 sm:mb-0">
                        <label class="inline-flex items-center cursor-pointer">
                            <input type="checkbox" data-day="${dayKey}" class="day-checkbox open-checkbox form-checkbox h-5 w-5 text-[var(--color-primary)] rounded focus:ring-[var(--color-highlight)]" ${config.is_open ? 'checked' : ''}>
                            <span class="ml-2 font-bold text-gray-700">${daysMap[dayKey]}</span>
                        </label>
                    </div>
                    <div class="flex gap-2 w-full sm:w-3/4 time-inputs" data-is-open="${config.is_open}">
                        <div class="w-1/2">
                            <label for="${dayKey}-open" class="text-xs text-gray-500 uppercase block">Abre</label>
                            <input type="time" id="${dayKey}-open" value="${openTimeDisplay}" class="w-full p-2 border border-gray-300 rounded-lg bg-white open-time" ${!config.is_open ? 'disabled' : ''}>
                        </div>
                        <div class="w-1/2">
                            <label for="${dayKey}-close" class="text-xs text-gray-500 uppercase block">Cierra</label>
                            <input type="time" id="${dayKey}-close" value="${closeTimeDisplay}" class="w-full p-2 border border-gray-300 rounded-lg bg-white close-time" ${!config.is_open ? 'disabled' : ''}>
                        </div>
                    </div>
                `;
                weeklyHoursList.appendChild(dayEl);
                // Asegurar que el estilo deshabilitado se aplique correctamente al cargar
                const openInput = dayEl.querySelector('.open-time');
                const closeInput = dayEl.querySelector('.close-time');
                toggleInputDisabledStyle(openInput, !config.is_open);
                toggleInputDisabledStyle(closeInput, !config.is_open);
            });

            // Añadir listeners para habilitar/deshabilitar inputs de tiempo
            weeklyHoursList.querySelectorAll('.day-checkbox').forEach(checkbox => {
                checkbox.addEventListener('change', function() {
                    const inputs = this.closest('.weekly-hour-day').querySelectorAll('input[type="time"]');
                    inputs.forEach(input => {
                        input.disabled = !this.checked;
                        toggleInputDisabledStyle(input, !this.checked);
                    });
                });
            });
        }

        // Modificamos para recibir el array de objetos de la BD
        function renderBlockedDates(datesArray) { 
            blockedDatesList.innerHTML = '';
            
            if (datesArray.length === 0 || !Array.isArray(datesArray)) {
                 blockedDatesList.innerHTML = '<p class="text-sm text-gray-500 text-center py-2">No hay días bloqueados.</p>';
                 return;
            }

            // Usamos el array de objetos con ID para la eliminación
            datesArray.forEach(item => {
                const dateStr = item.blocked_date;
                const date = new Date(dateStr + 'T00:00:00');
                const dateDisplay = date.toLocaleDateString('es-ES', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
                const dateEl = document.createElement('div');
                dateEl.className = 'flex justify-between items-center bg-white p-2 rounded-md shadow-sm border border-gray-100';
                dateEl.innerHTML = `
                    <span class="text-sm font-medium text-gray-700">${dateDisplay}</span>
                    <button type="button" class="text-[var(--color-secondary)]0 hover:text-[var(--color-secondary)] remove-blocked-date" data-id="${item.id}" data-date="${dateStr}" title="Desbloquear Fecha">
                        <i data-lucide="x" class="w-4 h-4"></i>
                    </button>
                `;
                blockedDatesList.appendChild(dateEl);
            });
            lucide.createIcons();
            setupBlockedDateListeners();
        }

        // Modificamos setupBlockedDateListeners para usar el ID de la fila para DELETE
        function setupBlockedDateListeners() {
            blockedDatesList.querySelectorAll('.remove-blocked-date').forEach(button => {
                button.removeEventListener('click', handleRemoveBlockedDate);
                button.addEventListener('click', handleRemoveBlockedDate);
            });
        }
        
        // FUNCIÓN: Eliminar Día Bloqueado (USA agenda-config-delete.php)
        async function handleRemoveBlockedDate(e) {
            e.preventDefault();
            const button = e.currentTarget;
            const idToRemove = button.dataset.id;
            const dateDisplay = button.dataset.date;
            if (!confirm(`¿Estás seguro de que deseas desbloquear la fecha ${dateDisplay}?`)) return;

             try {
                const response = await fetch('db/agenda-config-delete.php', {
                    method: 'POST', 
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ id: idToRemove }) 
                });
                const result = await response.json();
                if (result.status === 'success') {
                    showToast(`Fecha ${dateDisplay} desbloqueada con éxito.`, 'success');
                    // Recargar el panel para actualizar la lista de bloqueados
                    renderConfigPanel(); 
                    renderAgenda();
                } else {
                    showToast("Error al desbloquear fecha: " + result.message, 'error');
                }
            } catch (error) {
                showToast("Error de conexión al desbloquear la fecha.", 'error');
            }
        }


 // --- MANEJO DE EVENTOS Y ENVÍOS (CONECTADO A LOS ARCHIVOS CONFIG-PHP) ---

        // Nuevo Listener para abrir el panel de configuración
        if (configPanelOpenBtn) {
            configPanelOpenBtn.addEventListener('click', () => {
                // Abre el panel y luego carga los datos
                openPanel('configPanel'); 
                renderConfigPanel();
            });
        }

        // EVENTO: Guardar Capacidad y Duración (CORREGIDO)
        if (configCapacityForm) {
            configCapacityForm.addEventListener('submit', async function(e) {
                e.preventDefault();
                const slotDuration = parseInt(configSlotDuration.value);
                const capacity = parseInt(configCapacity.value);
                const saveButton = document.getElementById('save-capacity-btn');
                toggleButtonDisabledStyle(saveButton, true);

                if (isNaN(slotDuration) || slotDuration < 15 || isNaN(capacity) || capacity < 1) {
                    showToast("Por favor, introduce valores válidos para la duración (mín. 15) y capacidad (mín. 1).", 'warning');
                    toggleButtonDisabledStyle(saveButton, false);
                    return;
                }

                try {
                    const response = await fetch('db/agenda-config-update.php', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ action: 'update_schedule_config', slot_duration: slotDuration, capacity: capacity })
                    });
                    const result = await response.json();
                    if (result.status === 'success') {
                        showToast("Capacidad y duración actualizadas con éxito.", 'success');
                        // Actualizar variable global y recargar la agenda
                        dbScheduleConfig.slot_duration = slotDuration;
                        dbScheduleConfig.capacity = capacity;
                        renderAgenda();
                    } else {
                        showToast("Error al guardar capacidad: " + result.message, 'error');
                    }
                } catch (error) {
                    showToast("Error de conexión al guardar la configuración.", 'error');
                } finally {
                    toggleButtonDisabledStyle(saveButton, false);
                }
            });
        }

        // EVENTO: Guardar Horario Semanal (CORREGIDO)
        if (configWeeklyHoursForm) {
            configWeeklyHoursForm.addEventListener('submit', async function(e) {
                e.preventDefault();
                const saveButton = document.getElementById('save-weekly-hours-btn');
                toggleButtonDisabledStyle(saveButton, true);
                
                const updates = [];
                let hasInvalidHours = false;

                // CRÍTICO: Recorrer los elementos generados por renderWeeklyHours
                weeklyHoursList.querySelectorAll('.weekly-hour-day').forEach(dayRow => {
                    const checkbox = dayRow.querySelector('.open-checkbox');
                    const openTimeInput = dayRow.querySelector('.open-time');
                    const closeTimeInput = dayRow.querySelector('.close-time');

                    const day = dayRow.dataset.day; // Usar el data-day del contenedor
                    const isOpen = checkbox.checked;
                    const openTime = openTimeInput.value;
                    const closeTime = closeTimeInput.value;
                    
                    if (isOpen && openTime >= closeTime) {
                        showToast(`El horario de cierre para ${day} debe ser posterior al de apertura.`, 'warning');
                        hasInvalidHours = true;
                    }

                    // CRÍTICO: Asegurar formato HH:MM:SS y booleano/entero
                    updates.push({ 
                        day: day, 
                        is_open: isOpen ? 1 : 0, 
                        open_time: openTime + ':00', 
                        close_time: closeTime + ':00' 
                    });
                });

                if (hasInvalidHours) {
                    toggleButtonDisabledStyle(saveButton, false);
                    return;
                }

                try {
                    const response = await fetch('db/agenda-config-update.php', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ action: 'update_weekly_hours', updates: updates })
                    });
                    const result = await response.json();
                    if (result.status === 'success') {
                        showToast("Horario semanal actualizado con éxito.", 'success');
                        result.new_hours.forEach(item => {
                            dbWeeklyHours[item.day] = { 
                                is_open: item.is_open, 
                                open_time: item.open_time, 
                                close_time: item.close_time 
                            };
                        });
                        renderAgenda();
                        // Re-renderiza el panel para mostrar el estado actualizado de los inputs
                        renderWeeklyHours(); 
                    } else {
                        showToast("Error al guardar horario: " + result.message, 'error');
                    }
                } catch (error) {
                    showToast("Error de conexión al guardar el horario.", 'error');
                } finally {
                    toggleButtonDisabledStyle(saveButton, false);
                }
            });
        }

        // EVENTO: Añadir Día Bloqueado (USA agenda-config-create.php)
        if (addBlockedDateBtn) {
            addBlockedDateBtn.addEventListener('click', async function() {
                const dateToBlock = configBlockDate.value;
                
                // CRÍTICO: dbBlockedDates ahora es un array de objetos. 
                const blockedDatesArray = dbBlockedDates.map(item => item.blocked_date);
                
                if (!dateToBlock) {
                    showToast("Selecciona una fecha para bloquear.", 'warning');
                    return;
                }
                if (blockedDatesArray.includes(dateToBlock)) {
                    showToast("Esta fecha ya está bloqueada.", 'info');
                    return;
                }

                try {
                    const response = await fetch('db/agenda-config-create.php', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ blocked_date: dateToBlock })
                    });
                    const result = await response.json();
                    if (result.status === 'success' || result.status === 'warning') {
                        showToast(result.message, result.status);
                        // Llama a renderConfigPanel para recargar todo el panel y la lista de bloqueados
                        renderConfigPanel(); 
                        renderAgenda();
                        configBlockDate.value = '';
                    } else {
                        showToast("Error al bloquear fecha: " + result.message, 'error');
                    }
                } catch (error) {
                    showToast("Error de conexión al bloquear la fecha.", 'error');
                }
            });
        }
        
        // --- FUNCIONES HELPER GLOBALES ---

        // Ya se definió arriba, pero se incluye aquí para visibilidad.
        /* function toggleInputDisabledStyle(element, isDisabled) { ... } */
        function toggleButtonDisabledStyle(element, isDisabled) {
            element.disabled = isDisabled;
            if (isDisabled) {
                element.classList.add('opacity-50', 'cursor-not-allowed', 'pointer-events-none');
            } else {
                element.classList.remove('opacity-50', 'cursor-not-allowed', 'pointer-events-none');
            }
        }

        window.openPanel = function(panelId) {
            const panel = document.getElementById(panelId);
            if (!panel) { showToast(`Error: Panel con ID "${panelId}" no encontrado.`, 'error'); return; }

            if (panelId === 'agendarServicioPanel') {
                agendarServicioForm.reset();    
                citaClienteInfo.textContent = '';
                citaProspectoInfoAdicional.textContent = '';
                
                toggleInputDisabledStyle(citaClienteDisplay, false);
                toggleInputDisabledStyle(citaProspectoDisplay, false);
                
                const today = new Date();
                const todayFormatted = today.toISOString().split('T')[0];
                
                // Establecer la fecha de hoy por defecto y el mínimo
                citaFecha.value = todayFormatted;
                citaFecha.setAttribute('min', todayFormatted);
                
                // CRÍTICO: Generar y popular los slots basados en la fecha de hoy
                updateTimeSlots(todayFormatted); 
                
                // Añadir listener para actualizar los slots al cambiar la fecha
                citaFecha.removeEventListener('change', handleDateChangeForSlots);
                citaFecha.addEventListener('change', handleDateChangeForSlots);

                // Añadir listener para actualizar minutos al cambiar la hora
                citaHoraSelect.removeEventListener('change', handleHourChangeForMinutes);
                citaHoraSelect.addEventListener('change', handleHourChangeForMinutes);
            }

            panel.classList.remove('translate-x-full');
            panelOverlay.classList.remove('hidden');
            document.body.style.overflow = 'hidden';
        };

        // Handlers para los Listeners de tiempo
        function handleDateChangeForSlots() {
            updateTimeSlots(this.value);
            calculateAndDisplayNextRecurringDate();
        }

        function handleHourChangeForMinutes() {
            const slots = JSON.parse(this.dataset.slots || '[]');
            populateTimeSelect(citaMinutoSelect, 'minute', slots);
        }

        window.closePanel = function(panelId) {
            const panel = document.getElementById(panelId);
            if (!panel) { showToast(`Error: Panel con ID "${panelId}" no encontrado para cerrar.`, 'error'); return; }
            panel.classList.add('translate-x-full');
            panelOverlay.classList.add('hidden');
            document.body.style.overflow = '';
        };

        window.openModal = function(modalId) {
            const modal = document.getElementById(modalId);
            if (!modal) { showToast(`Error: Modal con ID "${modalId}" no encontrado.`, 'error'); return; }
            const modalBox = modal.querySelector('div:first-of-type');
            modal.classList.remove('hidden');
            setTimeout(() => { modalBox.classList.remove('scale-95', 'opacity-0'); }, 50);
            document.body.style.overflow = 'hidden';
        };

        window.closeModal = function(modalId) {
            const modal = document.getElementById(modalId);
            if (!modal) { showToast(`Error: Modal con ID "${modalId}" no encontrado para cerrar.`, 'error'); return; }
            const modalBox = modal.querySelector('div:first-of-type');
            modalBox.classList.add('scale-95', 'opacity-0');
            setTimeout(() => {  
                modal.classList.add('hidden');  
                document.body.style.overflow = '';
            }, 300);
        };

        window.openConfirmDeleteModal = function(itemId, itemType) {
            if (!confirmDeleteButton || !confirmItemTypeSpan) { showToast("Error: Elementos del modal de confirmación de eliminación no encontrados.", 'error'); return; }
            confirmDeleteButton.dataset.itemId = itemId; confirmDeleteButton.dataset.itemType = itemType;
            confirmItemTypeSpan.textContent = itemType.toUpperCase();
            openModal('confirmDeleteModal');
        };

        window.openViewCitaPanel = function(citaId, citaType) {
            let cita;
            if (citaType === 'unica') {
                cita = dbCitasUnicas[citaId];
            } else if (citaType === 'recurrente') {
                cita = dbCitasRecurrentes[citaId];
            }
            if (!cita) {
                showToast('[Agenda] Cita no encontrada: ' + citaId + ' ' + citaType, 'error');
                return;
            }

            // Set basic values
            viewCitaId.value = citaId;
            viewCitaType.value = citaType;
            viewCitaOriginalStatus.value = cita.status || '';

            const client = Object.values(dbClients).find(c => c.id == cita.client_id);
            viewCitaCliente.value = client ? client.name : (cita.client_name || '');
            viewCitaClienteInfo.textContent = client ? `Email: ${client.email || 'N/A'} | Tel: ${formatPhoneNumber(client.phone) || formatPhoneNumber(client.mobile_phone) || 'N/A'}` : '';
            toggleInputDisabledStyle(viewCitaCliente, true);

            const lead = Object.values(dbLeads).find(l => l.id == cita.lead_id);
            viewCitaProspecto.value = lead ? lead.name : (cita.prospect_name || '');
            viewCitaProspectoInfoAdicional.textContent = lead ? `Email: ${lead.email || 'N/A'} | Tel: ${formatPhoneNumber(lead.phone) || formatPhoneNumber(lead.mobile_phone) || 'N/A'}` : '';
            toggleInputDisabledStyle(viewCitaProspecto, true);

            viewCitaNotas.value = cita.notes || '';

            const now = new Date();
            const todayFormatted = now.toISOString().split('T')[0];
            viewCitaFecha.setAttribute('min', todayFormatted);

            const isCitaCompletedOrCancelled = cita.status === 'completed' || cita.status === 'cancelled';

            // Logic for unique vs recurring appointments
            if (citaType === 'unica') {
                viewCitaFechaGroup.classList.remove('hidden');
                viewCitaHoraGroup.classList.remove('hidden');
                viewCitaFrecuenciaGroup.classList.add('hidden');
                viewCitaProximaCitaGroup.classList.add('hidden');

                viewCitaFecha.value = cita.appointment_date || '';
                const [hora, minuto] = (cita.appointment_time || '00:00').split(':');
                
                // TODO: En la vista/edición de citas únicas, se debería recalcular los slots
                // Pero por ahora, se mantendrá la hora seleccionada para edición
                
                // Usamos la función original de populacion simple para evitar complejidad de regeneración de slots en edición por ahora
                // ya que los slots fijos ya fueron guardados
                populateTimeSelectOriginal(viewCitaHoraSelect, 'hour', hora); 
                populateTimeSelectOriginal(viewCitaMinutoSelect, 'minute', minuto);

                const citaDateTime = new Date(cita.appointment_date + 'T' + (cita.appointment_time || '00:00'));
                const isPastAppointment = citaDateTime < now;

                toggleInputDisabledStyle(viewCitaFecha, isPastAppointment || isCitaCompletedOrCancelled);
                toggleInputDisabledStyle(viewCitaHoraSelect, isPastAppointment || isCitaCompletedOrCancelled);
                toggleInputDisabledStyle(viewCitaMinutoSelect, isPastAppointment || isCitaCompletedOrCancelled);

            } else { // Recurring appointment
                viewCitaFechaGroup.classList.add('hidden');
                viewCitaHoraGroup.classList.add('hidden');
                viewCitaFrecuenciaGroup.classList.remove('hidden');
                viewCitaProximaCitaGroup.classList.remove('hidden');

                viewCitaFrecuencia.value = cita.frequency || '';
                const initialDateForCalculation = cita.next_appointment_date || cita.appointment_date; 
                const nextCalculatedDate = calculateNextRecurringDate(initialDateForCalculation, viewCitaFrecuencia.value);
                viewCitaProximaCitaDisplay.value = nextCalculatedDate.toLocaleDateString('es-ES', { year: 'numeric', month: 'long', day: 'numeric' });
                viewCitaProximaCita.value = nextCalculatedDate.toISOString().split('T')[0];

                toggleInputDisabledStyle(viewCitaFrecuencia, isCitaCompletedOrCancelled);
                toggleInputDisabledStyle(viewCitaProximaCitaDisplay, true); // Always readonly as it's calculated
            }

            // Disable notes and save button if completed or cancelled
            toggleInputDisabledStyle(viewCitaNotas, isCitaCompletedOrCancelled);
            toggleButtonDisabledStyle(saveCitaChangesBtn, isCitaCompletedOrCancelled);

            openPanel('viewCitaPanel');
        };
        
        // Versión original de populateTimeSelect para la edición de citas (donde no necesitamos lógica de slots complejos)
        function populateTimeSelectOriginal(selectElement, type, selectedValue = null) {
            selectElement.innerHTML = '';
            if (type === 'hour') {
                for (let i = 0; i < 24; i++) {
                    const option = document.createElement('option');
                    option.value = String(i).padStart(2, '0');
                    option.textContent = String(i).padStart(2, '0');
                    if (option.value === selectedValue) {
                        option.selected = true;
                    }
                    selectElement.appendChild(option);
                }
            } else if (type === 'minute') {
                for (let i = 0; i < 60; i += 15) {
                    const option = document.createElement('option');
                    option.value = String(i).padStart(2, '0');
                    option.textContent = String(i).padStart(2, '0');
                    if (option.value === selectedValue) {
                        option.selected = true;
                    }
                    selectElement.appendChild(option);
                }
            }
        }


        function updateViewRecurringDate() {
            const currentCitaId = viewCitaId.value;
            const currentCitaType = viewCitaType.value;
            let baseDateStr = '';
            
            if (currentCitaType === 'recurrente') {
                const citaObj = dbCitasRecurrentes[currentCitaId];
                if (citaObj) {
                    baseDateStr = citaObj.next_appointment_date || (new Date().toISOString().split('T')[0]); 
                }
            } else if (currentCitaType === 'unica') {
                baseDateStr = viewCitaFecha.value;
            }

            const frequency = viewCitaFrecuencia.value;

            if (baseDateStr && frequency) {
                const nextDate = calculateNextRecurringDate(baseDateStr, frequency);
                viewCitaProximaCitaDisplay.value = nextDate.toLocaleDateString('es-ES', { year: 'numeric', month: 'long', day: 'numeric' });
                viewCitaProximaCita.value = nextDate.toISOString().split('T')[0];
            } else {
                viewCitaProximaCitaDisplay.value = 'Selecciona una fecha y frecuencia';
                viewCitaProximaCita.value = '';
            }
        }
        
        // Ya se definió arriba, pero se incluye aquí para visibilidad.
        /* function toggleInputDisabledStyle(element, isDisabled) { ... } */
        /* function toggleButtonDisabledStyle(element, isDisabled) { ... } */

        function setupDeleteListeners() {
            document.querySelectorAll('.delete-btn').forEach(button => {
                button.removeEventListener('click', handleDeleteButtonClick);
                button.addEventListener('click', handleDeleteButtonClick);
            });
        }

        function handleDeleteButtonClick(e) {
            e.stopPropagation();
            const citaIdFull = this.dataset.itemId;
            const itemType = this.dataset.itemType;
            window.openConfirmDeleteModal(citaIdFull, itemType);
        }

        function setupEditListeners() {
            // Este es el punto crítico para asegurar que los listeners se adjunten
            document.querySelectorAll('.edit-cita-btn').forEach(button => {
                button.removeEventListener('click', handleEditCitaButtonClick); // Eliminar listener previo
                button.addEventListener('click', handleEditCitaButtonClick); // Adjuntar nuevo listener
            });
        }

        function handleEditCitaButtonClick(e) {
            e.stopPropagation();
            const citaId = this.dataset.citaId;
            const citaType = this.dataset.citaType;
            window.openViewCitaPanel(citaId, citaType);
        }

        function setupStatusActionListeners() {
            document.querySelectorAll('.action-complete-btn').forEach(button => {
                button.removeEventListener('click', handleCompleteCitaClick);
                button.addEventListener('click', handleCompleteCitaClick);
            });
            document.querySelectorAll('.action-cancel-btn').forEach(button => {
                button.removeEventListener('click', handleCancelCitaClick);
                button.addEventListener('click', handleCancelCitaClick);
            });
            document.querySelectorAll('.action-confirm-btn').forEach(button => {
                button.removeEventListener('click', handleConfirmCitaClick);
                button.addEventListener('click', handleConfirmCitaClick);
            });
            document.querySelectorAll('.action-message-btn').forEach(button => {
                button.removeEventListener('click', handleMessageCitaClick);
                button.addEventListener('click', handleMessageCitaClick);
            });
        }

        async function handleStatusUpdate(button, newStatus) {
            const citaIdFull = button.dataset.citaId;
            const citaType = button.dataset.citaType;
            const numericId = citaIdFull.split('-').pop();
            try {
                const response = await fetch('db/agenda-update.php', {
                    method: 'PUT',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ id: numericId, type: citaType, status: newStatus })
                });
                const result = await response.json();
                if (result.status === 'success') {
                    showToast(`Cita marcada como ${newStatus}.`, 'success');
                    if (citaType === 'unica') dbCitasUnicas[citaIdFull].status = newStatus;
                    else if (citaType === 'recurrente') dbCitasRecurrentes[citaIdFull].status = newStatus;
                    renderAppointmentList();
                    renderAgenda();
                } else {
                    showToast(`Error al actualizar estado: ${result.message}`, 'error');
                }
            } catch (error) {
                showToast('Hubo un problema de conexión al actualizar.', 'error');
            }
        }
        
        function handleCompleteCitaClick() { handleStatusUpdate(this, 'completed'); }
        function handleCancelCitaClick() { handleStatusUpdate(this, 'cancelled'); }
        function handleConfirmCitaClick() { handleStatusUpdate(this, 'confirmed'); }

        function handleMessageCitaClick() {
            const citaIdFull = this.dataset.citaId;
            const citaType = this.dataset.citaType;
            let cita = (citaType === 'unica') ? dbCitasUnicas[citaIdFull] : dbCitasRecurrentes[citaIdFull];

            if (!cita) {
                showToast(`Cita no encontrada para generar mensaje: ${citaIdFull}`, 'error');
                return;
            }

            const client = cita.client_id ? Object.values(dbClients).find(c => c.id == cita.client_id) : null;
            const prospect = cita.lead_id ? Object.values(dbLeads).find(l => l.id == cita.lead_id) : null;

            if (!client && !prospect) {
                showToast(`La cita no tiene un cliente o prospecto válido asociado.`, 'error');
                return;
            }

            const mainContact = client || prospect;
            const mainContactName = mainContact.first_name;
            const phoneToUse = mainContact.mobile_phone || mainContact.phone;

            const appointmentDetails = client && prospect ? ` con *${prospect.name}*` : '';

            msgCitaCliente.textContent = client ? client.name : 'N/A';
            msgCitaProspecto.textContent = prospect ? prospect.name : 'N/A';
            msgCitaFecha.textContent = new Date(cita.appointment_date + 'T00:00:00').toLocaleDateString('es-ES', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
            msgCitaHora.textContent = cita.appointment_time ? cita.appointment_time.substring(0, 5) : 'N/A';
            msgCitaTipo.textContent = cita.type === 'unica' ? 'Única' : 'Recurrente';
            msgCitaTelefono.textContent = formatPhoneNumber(phoneToUse) || 'N/A';

            const businessIdentifier = `${appSettings.contactName}, ${appSettings.companyName}`;
            const dateFormattedEs = new Date(cita.appointment_date + 'T00:00:00').toLocaleDateString('es-ES', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
            const timeFormatted = cita.appointment_time ? cita.appointment_time.substring(0, 5) : '';

            messageSpanish.value = `¡Hola ${mainContactName}!\n\nTe confirmo tu cita${appointmentDetails} el día *${dateFormattedEs}* a las *${timeFormatted}*.\n\n¡Nos vemos pronto!\n\nSaludos,\n${businessIdentifier}`;
            
            const dateFormattedEn = new Date(cita.appointment_date + 'T00:00:00').toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
            messageEnglish.value = `Hi ${mainContactName}!\n\nThis is to confirm your appointment${appointmentDetails} on *${dateFormattedEn}* at *${timeFormatted}*.\n\nSee you soon!\n\nRegards,\n${businessIdentifier}`;

            openPanel('messageCitaPanel');
        }

        copyMessageBtns.forEach(button => {
            button.addEventListener('click', async function() {
                const lang = this.dataset.lang;
                const messageTextArea = lang === 'es' ? messageSpanish : messageEnglish;
                try {
                    await navigator.clipboard.writeText(messageTextArea.value);
                    showToast(`Mensaje copiado al portapapeles.`, 'success');
                } catch (err) {
                    showToast('Error al copiar el mensaje.', 'error');
                }
            });
        });

        sendWhatsappBtns.forEach(button => {
            button.addEventListener('click', function() {
                const lang = this.dataset.lang;
                const messageTextArea = lang === 'es' ? messageSpanish : messageEnglish;
                let phoneNumber = msgCitaTelefono.textContent.replace(/\D/g, ''); // Usamos let para poder modificarlo

                if (phoneNumber && phoneNumber !== 'NA') {
                    // Lógica para agregar el '1' si es un número de 10 dígitos (para números de EE.UU.)
                    // Recordatorio: Estás en Chiquimulilla, Guatemala, por lo que esta lógica podría no ser universalmente aplicable
                    // y debería considerarse si tus clientes están en EE.UU. o Guatemala.
                    if (phoneNumber.length === 10) { // Assuming 10-digit numbers are US numbers
                        phoneNumber = '1' + phoneNumber;
                    }

                    const encodedMessage = encodeURIComponent(messageTextArea.value);
                    window.open(`https://wa.me/${phoneNumber}?text=${encodedMessage}`, '_blank');
                    showToast(`Abriendo WhatsApp...`, 'info');
                } else {
                    showToast('Número de teléfono no disponible.', 'warning');
                }
            });
        });

        function renderAgenda() {
            const calendarGrid = document.getElementById('calendar-grid');
            const periodTitle = document.getElementById('period-title');
            const monthlyTotal = document.getElementById('monthly-total');
            const monthlyNew = document.getElementById('monthly-new');
            const monthlyCancelled = document.getElementById('monthly-cancelled');
            const monthlyRecurring = document.getElementById('monthly-recurring');
            if (!calendarGrid || !periodTitle || !monthlyTotal || !monthlyNew || !monthlyCancelled || !monthlyRecurring) return;
            calendarGrid.innerHTML = '';
            const todayAtMidnight = new Date();
            todayAtMidnight.setHours(0, 0, 0, 0);
            let displayStartDate, daysToRender;
            if (currentView === 'weekly') {
                const startOfWeek = new Date(currentDate);
                startOfWeek.setDate(startOfWeek.getDate() - startOfWeek.getDay());
                displayStartDate = startOfWeek;
                const displayEndDate = new Date(startOfWeek);
                displayEndDate.setDate(displayEndDate.getDate() + 6);
                periodTitle.textContent = `${displayStartDate.toLocaleDateString('es-ES', {day: 'numeric', month: 'short'}).toUpperCase()} - ${displayEndDate.toLocaleDateString('es-ES', {day: 'numeric', month: 'short', year: 'numeric'}).toUpperCase()}`;
                daysToRender = 7;
                // MODIFICACIÓN: Añadir clase para la vista semanal en móvil para activar el grid de 2 en 2
                calendarGrid.className = 'grid grid-cols-1 md:grid-cols-7 gap-px bg-gray-200 border border-gray-200 rounded-lg overflow-hidden weekly-mobile-grid';
                viewWeeklyBtn.className = 'btn-secondary font-bold py-2 px-4 rounded-lg uppercase';
                viewMonthlyBtn.className = 'bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase';
            } else {
                const startOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
                displayStartDate = startOfMonth;
                periodTitle.textContent = `${displayStartDate.toLocaleDateString('es-ES', {month: 'long', year: 'numeric'}).toUpperCase()}`;
                let firstDayOfMonth = startOfMonth.getDay();
                let startGridDate = new Date(startOfMonth);
                startGridDate.setDate(startOfMonth.getDate() - firstDayOfMonth);
                daysToRender = 42;
                // MODIFICACIÓN CLAVE: Clases responsivas para la cuadrícula del calendario y altura mínima
                // Se ha ajustado el min-h para la vista mensual para que sea más compacto en móviles.
                calendarGrid.className = 'grid grid-cols-7 gap-px bg-gray-200 border border-gray-200 rounded-lg overflow-hidden';
                // REMOVER CLASE weekly-mobile-grid para que no afecte la vista mensual
                calendarGrid.classList.remove('weekly-mobile-grid');
                displayStartDate = startGridDate;
                viewMonthlyBtn.className = 'btn-secondary font-bold py-2 px-4 rounded-lg uppercase';
                viewWeeklyBtn.className = 'bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase';
            }
            const currentMonthStart = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
            const nextMonthStart = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1);
            const monthlyUniqueAppointments = Object.values(dbCitasUnicas).filter(c => {
                const citaDate = new Date(c.appointment_date + 'T00:00:00');
                return citaDate >= currentMonthStart && citaDate < nextMonthStart;
            });
            const monthlyRecurringAppointments = Object.values(dbCitasRecurrentes).filter(c => {
                const nextCitaDate = new Date(c.next_appointment_date + 'T00:00:00');
                return nextCitaDate >= currentMonthStart && nextCitaDate < nextMonthStart;
            });
            monthlyTotal.textContent = (monthlyUniqueAppointments.length + monthlyRecurringAppointments.length).toString();
            monthlyNew.textContent = monthlyUniqueAppointments.filter(c => c.status === 'pending' || c.status === 'confirmed').length.toString();
            monthlyCancelled.textContent = monthlyUniqueAppointments.filter(c => c.status === 'cancelled').length.toString();
            monthlyRecurring.textContent = monthlyRecurringAppointments.filter(c => c.type === 'recurrente').length.toString(); // CORRECCIÓN: Filtrar recurrentes
            for (let i = 0; i < daysToRender; i++) {
                const day = new Date(displayStartDate);
                day.setDate(day.getDate() + i);
                const dayCol = document.createElement('div');
                // MODIFICACIÓN CLAVE: min-h para vista mensual en móvil (más compacto)
                // Se ha ajustado el min-h para la vista mensual para que sea más compacto en móviles.
                const minHeightClass = currentView === 'monthly' ? 'min-h-[70px] sm:min-h-[100px] md:min-h-[150px]' : 'min-h-[150px]';
                dayCol.className = `bg-white p-2 ${minHeightClass} calendar-day-clickable relative`;
                dayCol.dataset.date = day.toISOString().split('T')[0];
                const isToday = day.toDateString() === todayAtMidnight.toDateString();
                const isOutsideMonth = currentView === 'monthly' && (day.getMonth() !== currentDate.getMonth());
                dayCol.innerHTML = `<div class="calendar-day-header text-center p-2 mb-2 rounded-lg ${isToday ? 'today' : ''} ${isOutsideMonth ? 'opacity-50' : ''}"><p class="font-bold text-sm">${day.toLocaleDateString('es-ES', { weekday: 'short' }).toUpperCase()}</p><p class="text-2xl font-bold">${day.getDate()}</p></div><div class="space-y-2 appointment-list-day overflow-y-auto max-h-[90px] pr-1 -mr-1"></div>`;
                const appointmentListDayEl = dayCol.querySelector('.appointment-list-day');
                const dayString = day.toISOString().split('T')[0];
                
                const appointmentsForDay = Object.values(dbCitasUnicas)
                    .filter(cita => cita.appointment_date === dayString && new Date(cita.appointment_date + 'T' + cita.appointment_time) >= todayAtMidnight && cita.status !== 'cancelled' && cita.status !== 'completed')
                    .map(cita => ({...cita, id: `cita-unica-${cita.id}`}))
                    .sort((a,b) => a.appointment_time.localeCompare(b.appointment_time));

                const recurringForDay = Object.values(dbCitasRecurrentes).filter(recCita => recCita.next_appointment_date === dayString && new Date(recCita.next_appointment_date + 'T00:00:00') >= todayAtMidnight).map(recCita => ({...recCita, id: `cita-recurrente-${recCita.id}`, type: 'recurrente', appointment_time: 'N/A', status: 'confirmed', appointment_date: recCita.next_appointment_date}));
                const allDayAppointments = [...appointmentsForDay, ...recurringForDay].sort((a,b) => (a.appointment_time || '00:00').localeCompare(b.appointment_time || '00:00'));
                
                if (allDayAppointments.length > 0) {
                    allDayAppointments.forEach(cita => {
                        const appointmentEl = document.createElement('div');
                        let statusClasses = '', statusIcon = '';
                        if (cita.status === 'cancelled') { statusClasses = 'cancelled'; statusIcon = '<i data-lucide="x-circle" class="w-4 h-4 text-gray-500"></i>'; }
                        else if (cita.status === 'completed') { statusClasses = 'completed'; statusIcon = '<i data-lucide="check-circle" class="w-4 h-4 text-green-600"></i>'; }
                        else if (cita.type === 'recurrente') { statusIcon = '<i data-lucide="repeat" class="w-4 h-4 text-blue-600"></i>'; }
                        else if (cita.status === 'pending') { statusClasses = 'bg-orange-100'; statusIcon = '<i data-lucide="bell" class="w-4 h-4 text-orange-500"></i>'; } // Aquí se utiliza el estilo 'pending' del CSS
                        else if (cita.status === 'confirmed') { statusClasses = 'bg-blue-100'; statusIcon = '<i data-lucide="check" class="w-4 h-4 text-blue-600"></i>'; }
                        else { statusClasses = 'bg-gray-100'; statusIcon = '<i data-lucide="help-circle" class="w-4 h-4 text-gray-500"></i>'; }

                        // Ajuste en las clases para la visualización del estado
                        const statusBadgeClass = `px-2 py-1 rounded-full text-xs font-semibold uppercase ${statusClasses}`;

                        appointmentEl.className = `appointment-card bg-blue-50 p-2 rounded-md text-xs cursor-pointer hover:bg-blue-100 relative`;
                        appointmentEl.dataset.citaId = cita.id;
                        appointmentEl.dataset.citaType = cita.type || 'unica';
                        // Event listener para abrir el panel de vista/edición de cita
                        appointmentEl.addEventListener('click', (e) => { e.stopPropagation(); window.openViewCitaPanel(cita.id, cita.type || 'unica'); });
                        appointmentEl.innerHTML = `
                            <p class="font-bold uppercase flex items-center gap-1">
                                ${cita.appointment_time === 'N/A' ? 'Recurrente' : cita.appointment_time.substring(0, 5)}
                            </p>
                            <p class="truncate uppercase">${cita.associated_entity_name || ''}</p>
                            <div class="absolute top-1 right-1 flex items-center justify-center">
                                ${statusIcon}
                            </div>
                        `;
                        appointmentListDayEl.appendChild(appointmentEl);
                    });
                } else {
                    appointmentListDayEl.innerHTML = `<p class="text-xs text-center text-gray-400 mt-4 uppercase">SIN CITAS</p>`;
                }
                calendarGrid.appendChild(dayCol);
            }
            // Re-adjuntar listeners a los días del calendario
            calendarGrid.querySelectorAll('.calendar-day-clickable').forEach(dayElement => {
                const oldListener = dayElement._clickListener;
                if (oldListener) dayElement.removeEventListener('click', oldListener);
                const newListener = function() {
                    const clickedDate = new Date(this.dataset.date + 'T00:00:00');
                    const today = new Date(); today.setHours(0, 0, 0, 0);
                    if (clickedDate < today) {
                        showToast(`No se puede agendar en fechas pasadas.`, 'info');
                        return;    
                    }
                    citaFecha.value = this.dataset.date;
                    openPanel('agendarServicioPanel');
                };
                dayElement.addEventListener('click', newListener);
                dayElement._clickListener = newListener;
            });
            renderAppointmentList(); // Llamar para la lista de abajo
            lucide.createIcons(); // Re-renderizar iconos
        }

        function renderAppointmentList() {
            const listEl = document.getElementById('appointment-list');
            listEl.innerHTML = '';
            const searchTerm = appointmentSearch.value.toLowerCase();
            const filterStatusValue = appointmentFilterStatus.value;
            const filterType = appointmentFilterType.value;
            const todayAtMidnight = new Date();
            todayAtMidnight.setHours(0, 0, 0, 0);
            const allUnique = Object.values(dbCitasUnicas).map(c => ({...c, id: `cita-unica-${c.id}`, type: 'unica'}));
            const allRecurring = Object.values(dbCitasRecurrentes).map(c => ({...c, id: `cita-recurrente-${c.id}`, type: 'recurrente', status: 'confirmed', appointment_date: c.next_appointment_date, appointment_time: 'N/A'}));
            const combinedAppointments = [...allUnique, ...allRecurring];
            const filteredAppointments = combinedAppointments.filter(cita => {
                const clientName = cita.associated_entity_type === 'client' ? (cita.associated_entity_name || '') : '';
                const prospectName = cita.associated_entity_type === 'lead' ? (cita.associated_entity_name || '') : '';
                const matchesSearch = (clientName.toLowerCase().includes(searchTerm)) || (prospectName.toLowerCase().includes(searchTerm)) || (cita.notes && cita.notes.toLowerCase().includes(searchTerm));
                const matchesType = (filterType === 'all') || (cita.type === filterType);
                const citaDate = new Date(cita.appointment_date + (cita.appointment_time && cita.appointment_time !== 'N/A' ? 'T' + cita.appointment_time : 'T00:00:00'));
                let matchesStatusAndDate = false;
                switch (filterStatusValue) {
                    case 'all': case 'todas': matchesStatusAndDate = true; break;
                    case 'hoy': matchesStatusAndDate = citaDate >= todayAtMidnight && citaDate < new Date(todayAtMidnight.getTime() + 24 * 60 * 60 * 1000) && cita.status !== 'cancelled' && cita.status !== 'completed'; break;
                    case 'proximas': matchesStatusAndDate = citaDate >= todayAtMidnight && cita.status !== 'cancelled' && cita.status !== 'completed'; break;
                    case 'pasadas': matchesStatusAndDate = citaDate < todayAtMidnight; break;
                    default: matchesStatusAndDate = cita.status === filterStatusValue; break;
                }
                return matchesSearch && matchesType && matchesStatusAndDate;
            }).sort((a,b) => new Date(a.appointment_date + 'T' + (a.appointment_time || '00:00')) - new Date(b.appointment_date + 'T' + (b.appointment_time || '00:00')));
            
            if (filteredAppointments.length === 0) {
                listEl.innerHTML = `<p class="text-center text-gray-500 py-4 uppercase">NO HAY CITAS CON ESTOS FILTROS.</p>`;
                return;
            }
            
            filteredAppointments.forEach(cita => {
                const itemEl = document.createElement('div');
                // Aplica clases para que el ítem de la lista se comporte como una "fila" responsive
                itemEl.className = `appointment-list-item flex flex-col sm:flex-row items-start sm:items-center p-4 rounded-lg border bg-white`;
                
                const isCancelled = cita.status === 'cancelled', isCompleted = cita.status === 'completed', isRecurring = cita.type === 'recurrente';
                let statusDisplayHtml = '', iconColorClass = '', actionButtonsHtml = '';

                // Determina las clases de estado y el ícono
                if (isCancelled) { statusDisplayHtml = '<span class="px-2 py-1 bg-gray-200 text-gray-700 rounded-full text-xs font-semibold uppercase">CANCELADA</span>'; iconColorClass = 'text-gray-500'; }
                else if (isCompleted) { statusDisplayHtml = '<span class="px-2 py-1 bg-green-200 text-green-700 rounded-full text-xs font-semibold uppercase">COMPLETADA</span>'; iconColorClass = 'text-green-600'; }
                else if (isRecurring) { statusDisplayHtml = '<span class="px-2 py-1 bg-blue-100 text-blue-700 rounded-full text-xs font-semibold uppercase">RECURRENTE</span>'; iconColorClass = 'text-blue-600'; }
                else if (cita.status === 'pending') { statusDisplayHtml = '<span class="px-2 py-1 bg-orange-100 text-orange-700 rounded-full text-xs font-semibold uppercase">PENDIENTE</span>'; iconColorClass = 'text-orange-500'; actionButtonsHtml = `<button class="bg-blue-600 hover:bg-blue-700 text-white py-1 px-2 rounded-md text-xs uppercase action-confirm-btn" data-cita-id="${cita.id}" data-cita-type="${cita.type}" title="Confirmar Cita">Confirmar</button><button class="bg-yellow-500 hover:bg-yellow-600 text-white py-1 px-2 rounded-md text-xs uppercase action-cancel-btn" data-cita-id="${cita.id}" data-cita-type="${cita.type}" title="Marcar como Cancelada">Cancelar</button><button class="bg-purple-600 hover:bg-purple-700 text-white py-1 px-2 rounded-md text-xs uppercase action-message-btn" data-cita-id="${cita.id}" data-cita-type="${cita.type}" title="Enviar Mensaje de Confirmación">Mensaje</button>`; }
                else if (cita.status === 'confirmed') { statusDisplayHtml = '<span class="px-2 py-1 bg-primary-100 text-[var(--color-primary)] rounded-full text-xs font-semibold uppercase">CONFIRMADA</span>'; iconColorClass = 'text-[var(--color-primary)]'; actionButtonsHtml = `<button class="btn-primary py-1 px-2 rounded-md text-xs uppercase action-complete-btn" data-cita-id="${cita.id}" data-cita-type="${cita.type}" title="Marcar como Completada">Completar</button><button class="bg-yellow-500 hover:bg-yellow-600 text-white py-1 px-2 rounded-md text-xs uppercase action-cancel-btn" data-cita-id="${cita.id}" data-cita-type="${cita.type}" title="Marcar como Cancelada">Cancelar</button>`; }
                else { statusDisplayHtml = '<span class="px-2 py-1 bg-gray-100 text-gray-500 rounded-full text-xs font-semibold uppercase">DESCONOCIDO</span>'; iconColorClass = 'text-gray-400'; }
                let statusIconHtml = '';
                if (isCancelled) statusIconHtml = `<i data-lucide="x-circle" class="w-5 h-5 ${iconColorClass} mr-2"></i>`;
                else if (isCompleted) statusIconHtml = `<i data-lucide="check-circle" class="w-5 h-5 ${iconColorClass} mr-2"></i>`;
                else if (isRecurring) statusIconHtml = `<i data-lucide="repeat" class="w-5 h-5 ${iconColorClass} mr-2"></i>`;
                else statusIconHtml = `<i data-lucide="calendar-check" class="w-5 h-5 ${iconColorClass} mr-2"></i>`;
                
                // HTML de la cita en la lista - Ajustado para vista móvil
                itemEl.innerHTML = `
                    <div class="flex-shrink-0 w-full sm:w-1/6 text-left sm:text-center mr-4 mb-2 sm:mb-0">
                        <p class="font-bold text-lg text-[var(--color-primary)]" data-label="DÍA">${new Date(cita.appointment_date + 'T00:00:00').toLocaleDateString('es-ES', {day: 'numeric'})}</p>
                        <p class="text-xs text-gray-500 uppercase" data-label="MES">${new Date(cita.appointment_date + 'T00:00:00').toLocaleDateString('es-ES', {month: 'short'}).toUpperCase()}</p>
                    </div>
                    <div class="flex-grow flex flex-col sm:flex-row sm:items-center sm:justify-between w-full sm:w-auto">
                        <div class="flex-grow mb-2 sm:mb-0">
                            <p class="font-bold ${isCancelled ? 'line-through text-gray-500' : 'text-gray-800'} uppercase flex items-center">
                                ${statusIconHtml} ${cita.associated_entity_name} ${isRecurring ? `(${cita.frequency.toUpperCase()})` : ''}
                            </p>
                            <p class="text-sm ${isCancelled ? 'line-through text-gray-400' : 'text-gray-600'} uppercase" data-label="HORA">
                                ${isRecurring ? 'Cita recurrente' : `A LAS ${cita.appointment_time ? cita.appointment_time.substring(0, 5) : 'N/A'}`}
                            </p>
                            <div class="mt-1" data-label="ESTADO">${statusDisplayHtml}</div>
                        </div>
                        <div class="flex items-center space-x-2 flex-shrink-0">
                            ${actionButtonsHtml}
                            <button class="text-blue-600 hover:bg-blue-800 edit-cita-btn" title="Editar Cita" data-cita-id="${cita.id}" data-cita-type="${cita.type}"><i data-lucide="edit-2" class="w-5 h-5"></i></button>
                            <button class="text-[var(--color-secondary)] hover:text-v delete-btn" data-item-type="${cita.type}" data-item-id="${cita.id}" title="Eliminar Cita"><i data-lucide="trash-2" class="w-5 h-5"></i></button>
                        </div>
                    </div>
                `;
                listEl.appendChild(itemEl);
            });
            lucide.createIcons();
            setupEditListeners();
            setupDeleteListeners();
            setupStatusActionListeners();
        }
        
        if (confirmDeleteButton) {
            confirmDeleteButton.addEventListener('click', async function() {
                const itemId = this.dataset.itemId;
                const itemType = this.dataset.itemType;
                try {
                    const response = await fetch('db/agenda-delete.php', {
                        method: 'DELETE',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ id: itemId, type: itemType })
                    });
                    const result = await response.json();
                    if (result.status === 'success') {
                        showToast(`${itemType} eliminada con éxito.`, 'success');
                        if (itemType === 'unica') delete dbCitasUnicas[itemId];
                        else if (itemType === 'recurrente') delete dbCitasRecurrentes[itemId];
                        renderAppointmentList();
                        renderAgenda();
                    } else {
                        showToast(`Error al eliminar: ${result.message}`, 'error');
                    }
                } catch (error) {
                    showToast('Hubo un problema de conexión al eliminar.', 'error');
                }
                window.closeModal('confirmDeleteModal');
            });
        }
        
        if(prevBtn) prevBtn.addEventListener('click', () => { if (currentView === 'weekly') currentDate.setDate(currentDate.getDate() - 7); else currentDate.setMonth(currentDate.getMonth() - 1); renderAgenda(); });
        if(nextBtn) nextBtn.addEventListener('click', () => { if (currentView === 'weekly') currentDate.setDate(currentDate.getDate() + 7); else currentDate.setMonth(currentDate.getMonth() + 1); renderAgenda(); });
        if(viewWeeklyBtn) viewWeeklyBtn.addEventListener('click', () => { currentView = 'weekly'; renderAgenda(); });
        if(viewMonthlyBtn) viewMonthlyBtn.addEventListener('click', () => { currentView = 'monthly'; renderAgenda(); });
        
        if (agendarServicioForm) {
            citaRecurrenteCheckbox.addEventListener('change', function() {
                recurrenciaOptionsDiv.classList.toggle('hidden', !this.checked);
                calculateAndDisplayNextRecurringDate();
            });
            // Listener de cambio de fecha ya está configurado en openPanel
            // citaFecha.addEventListener('change', handleDateChangeForSlots); 
            citaFrecuenciaSelect.addEventListener('change', calculateAndDisplayNextRecurringDate);

            function calculateAndDisplayNextRecurringDate() {
                if (citaRecurrenteCheckbox.checked) {
                    const initialDateStr = citaFecha.value;
                    const frequency = citaFrecuenciaSelect.value;
                    if (initialDateStr && frequency) {
                        const nextDate = calculateNextRecurringDate(initialDateStr, frequency);
                        citaProximaCitaDisplay.value = nextDate.toLocaleDateString('es-ES', { year: 'numeric', month: 'long', day: 'numeric' });
                        citaProximaCitaInput.value = nextDate.toISOString().split('T')[0];
                    } else {
                        citaProximaCitaDisplay.value = 'Selecciona fecha y frecuencia';
                        citaProximaCitaInput.value = '';
                    }
                }
            }

            function calculateNextRecurringDate(initialDateStr, frequency) {
                const initialDate = new Date(initialDateStr + 'T00:00:00');
                let nextDate = new Date(initialDate);
                switch (frequency) {
                    case 'weekly': nextDate.setDate(nextDate.getDate() + 7); break;
                    case 'bi-weekly': nextDate.setDate(nextDate.getDate() + 14); break;
                    case 'monthly': nextDate.setMonth(nextDate.getMonth() + 1); if (nextDate.getDate() < initialDate.getDate()) nextDate = new Date(nextDate.getFullYear(), nextDate.getMonth() + 1, 0); break;
                }
                return nextDate;
            }

            function setupAutocomplete(displayEl, inputEl, suggestionsEl, data, type, infoEl) {
                let searchTimeout = null;
                displayEl.addEventListener('input', function() {
                    const otherDisplayEl = type === 'client' ? citaProspectoDisplay : citaClienteDisplay;
                    
                    clearTimeout(searchTimeout);
                    const searchTerm = this.value.toLowerCase();
                    inputEl.value = '';
                    if (infoEl) infoEl.textContent = '';
                    suggestionsEl.innerHTML = '';
                    if (searchTerm.length < 2) {
                        suggestionsEl.classList.add('hidden');
                        return;
                    }
                    searchTimeout = setTimeout(() => {
                        const filteredData = Object.values(data).filter(item => 
                            item.name.toLowerCase().includes(searchTerm) || 
                            (item.email && item.email.toLowerCase().includes(searchTerm)) ||
                            (item.phone && item.phone.includes(searchTerm)) ||
                            (item.mobile_phone && item.mobile_phone.includes(searchTerm))
                        );
                        if (filteredData.length > 0) {
                            filteredData.forEach(item => {
                                const suggestionItem = document.createElement('div');
                                suggestionItem.className = 'autocomplete-suggestion';
                                suggestionItem.textContent = `${item.name} (${item.email || item.phone || item.mobile_phone || 'N/A'})`;
                                suggestionItem.addEventListener('click', () => {
                                    displayEl.value = item.name;
                                    inputEl.value = item.id;
                                    if (infoEl) infoEl.textContent = `Email: ${item.email || 'N/A'} | Tel: ${formatPhoneNumber(item.phone) || formatPhoneNumber(item.mobile_phone) || 'N/A'}`;
                                    suggestionsEl.classList.add('hidden');
                                    showToast(`${type === 'client' ? 'Cliente' : 'Prospecto'} "${item.name}" seleccionado.`, 'info');
                                    
                                    // CRÍTICO: BLOQUEAR el otro campo al seleccionar
                                    const otherInputDisplay = type === 'client' ? citaProspectoDisplay : citaClienteDisplay;
                                    const otherInputHidden = type === 'client' ? citaProspectoInput : citaClienteInput;
                                    const otherInfoEl = type === 'client' ? citaProspectoInfoAdicional : citaClienteInfo;
                                    
                                    otherInputDisplay.value = '';
                                    otherInputHidden.value = '';
                                    if (otherInfoEl) otherInfoEl.textContent = '';
                                    toggleInputDisabledStyle(otherInputDisplay, true); // Bloquear el otro
                                    toggleInputDisabledStyle(displayEl, false); // Asegurar que este esté desbloqueado
                                });
                                suggestionsEl.appendChild(suggestionItem);
                            });
                            suggestionsEl.classList.remove('hidden');
                        } else {
                            suggestionsEl.classList.add('hidden');
                        }
                    }, 300);
                });
                displayEl.addEventListener('blur', () => {
                    setTimeout(() => suggestionsEl.classList.add('hidden'), 150);
                });
                
                // CRÍTICO: Habilitar el otro campo al vaciar este
                displayEl.addEventListener('change', function() {
                    if (this.value.trim() === '') {
                        const otherInputDisplay = type === 'client' ? citaProspectoDisplay : citaClienteDisplay;
                        toggleInputDisabledStyle(otherInputDisplay, false); // Desbloquear el otro
                        inputEl.value = '';
                        if (infoEl) infoEl.textContent = '';
                    }
                });
            }

            setupAutocomplete(citaClienteDisplay, citaClienteInput, citaClienteSuggestions, dbClients, 'client', citaClienteInfo);
            setupAutocomplete(citaProspectoDisplay, citaProspectoInput, citaProspectoSuggestions, dbLeads, 'prospect', citaProspectoInfoAdicional);

            agendarServicioForm.addEventListener('submit', async function(e) {
                e.preventDefault();
                const client_id = citaClienteInput.value;
                const lead_id = citaProspectoInput.value;
                const appointment_date = citaFecha.value;

                if (!(client_id || lead_id) || !appointment_date) {
                    showToast("Por favor, selecciona una fecha y un Cliente O un Prospecto.", 'warning');
                    return;
                }
                
                // Validación crítica de slots
                if (!citaRecurrenteCheckbox.checked) {
                    const hora = citaHoraSelect.value;
                    const minuto = citaMinutoSelect.value;
                    if (!hora || !minuto) {
                         showToast("Debes seleccionar una hora y minuto válidos según tu horario de servicio.", 'warning');
                        return;
                    }
                }


                const notes = citaNotas.value;
                const is_recurring = citaRecurrenteCheckbox.checked;
                
                let citaData = {
                    client_id: client_id || null,
                    lead_id: lead_id || null,
                    notes: notes,
                    type: is_recurring ? 'recurrente' : 'unica'
                };

                if (is_recurring) {
                    const frequency = citaFrecuenciaSelect.value;
                    const next_appointment_date = citaProximaCitaInput.value;
                    if (!frequency || !next_appointment_date) {
                        showToast("Por favor, selecciona una frecuencia y una próxima fecha.", 'warning');
                        return;
                    }
                    citaData.frequency = frequency;
                    citaData.next_appointment_date = next_appointment_date;
                } else {
                    citaData.appointment_date = appointment_date;
                    citaData.appointment_time = `${citaHoraSelect.value}:${citaMinutoSelect.value}:00`;
                    citaData.status = 'pending';
                }
                try {
                    const response = await fetch('db/agenda-create.php', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(citaData)
                    });
                    const result = await response.json();
                    if (result.status === 'success') {
                        showToast("Cita agendada con éxito. Recargando datos...", 'success');
                        closePanel('agendarServicioPanel');
                        location.reload();    
                    } else {
                        showToast("Error al agendar cita: " + result.message, 'error');
                    }
                } catch (error) {
                    showToast("Hubo un problema de conexión al agendar la cita.", 'error');
                }
            });
        }
        
        if (viewCitaForm) {
            viewCitaFrecuencia.addEventListener('change', updateViewRecurringDate);
            viewCitaFecha.addEventListener('change', updateViewRecurringDate);
            viewCitaForm.addEventListener('submit', async function(e) {
                e.preventDefault();
                const cita_id_full = viewCitaId.value;
                const cita_type = viewCitaType.value;
                const numeric_id = cita_id_full.split('-').pop();
                const notes = viewCitaNotas.value;
                let updateData = {
                    id: numeric_id,
                    type: cita_type,
                    notes: notes
                };
                if (cita_type === 'unica') {
                    const appointment_date = viewCitaFecha.value;
                    const appointment_time = `${viewCitaHoraSelect.value}:${viewCitaMinutoSelect.value}:00`;
                    if (!appointment_date || !appointment_time) {
                        showToast("Por favor, selecciona una fecha y hora.", 'warning');
                        return;
                    }
                    updateData.appointment_date = appointment_date;
                    updateData.appointment_time = appointment_time;
                } else if (cita_type === 'recurrente') {
                    const frequency = viewCitaFrecuencia.value;
                    if (!frequency) {
                        showToast("Por favor, selecciona una frecuencia.", 'warning');
                        return;
                    }
                    updateData.frequency = frequency;
                    // También se actualiza la próxima cita si se cambia la frecuencia
                    // aunque la lógica de cálculo debe estar en el backend en producción.
                    const baseDate = dbCitasRecurrentes[cita_id_full]?.next_appointment_date || viewCitaFecha.value;
                    updateData.next_appointment_date = calculateNextRecurringDate(baseDate, frequency).toISOString().split('T')[0];
                }
                try {
                    const response = await fetch('db/agenda-update.php', {
                        method: 'PUT',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(updateData)
                    });
                    const result = await response.json();
                    if (result.status === 'success') {
                        showToast("Cambios guardados con éxito. Recargando datos...", 'success');
                        closePanel('viewCitaPanel');
                        location.reload();    
                    } else {
                        showToast("Error al guardar cambios: " + result.message, 'error');
                    }
                } catch (error) {
                    showToast("Hubo un problema de conexión al guardar los cambios.", 'error');
                }
            });
        }
        
        if (appointmentSearch) appointmentSearch.addEventListener('input', renderAppointmentList);
        if (appointmentFilterStatus) appointmentFilterStatus.addEventListener('change', renderAppointmentList);
        if (appointmentFilterType) appointmentFilterType.addEventListener('change', renderAppointmentList);
        
        if (downloadCitasBtn) {
            downloadCitasBtn.addEventListener('click', function(e) {
                e.stopPropagation();
                downloadDropdown.classList.toggle('hidden');
            });
            document.addEventListener('click', function(e) {
                if (!downloadDropdown.contains(e.target) && !downloadCitasBtn.contains(e.target)) {
                    downloadDropdown.classList.add('hidden');
                }
            });
            exportCsvBtn.addEventListener('click', () => {
                const allAppointments = [...Object.values(dbCitasUnicas), ...Object.values(dbCitasRecurrentes)];
                if (allAppointments.length > 0) {
                    showToast('Preparando descarga CSV...', 'info');
                    const dataToExport = allAppointments.map(cita => ({
                        ID: String(cita.id).match(/(\d+)$/)?.[1] || cita.id,
                        Tipo: cita.type,
                        Asociado: cita.associated_entity_name,
                        Fecha: cita.appointment_date || cita.next_appointment_date,
                        Hora: cita.appointment_time || 'N/A',
                        Estado: cita.status || 'N/A',
                        Frecuencia: cita.frequency || 'N/A',
                        Notas: cita.notes
                    }));
                    descargarComoCSV(dataToExport, 'agenda.csv');
                } else {
                    showToast('No hay citas para descargar.', 'info');
                }
                downloadDropdown.classList.add('hidden');
            });
            exportIcalBtn.addEventListener('click', () => {
                const allAppointments = [...Object.values(dbCitasUnicas), ...Object.values(dbCitasRecurrentes)];
                if (allAppointments.length > 0) {
                    showToast('Preparando descarga iCalendar...', 'info');
                    const dataToExport = allAppointments.map(cita => ({
                        id: String(cita.id).match(/(\d+)$/)?.[1] || cita.id,
                        type: cita.type,
                        associated_entity_name: cita.associated_entity_name,
                        appointment_date: cita.appointment_date || cita.next_appointment_date,
                        appointment_time: cita.appointment_time || '00:00:00',
                        notes: cita.notes,
                        frequency: cita.frequency || ''
                    }));
                    descargarComoICS(dataToExport, 'agenda.ics');
                } else {
                    showToast('No hay citas para descargar.', 'info');
                }
                downloadDropdown.classList.add('hidden');
            });
        }

        if (dbErrorMessage) showToast(dbErrorMessage, 'error');
        
        // --- LLAMADA INICIAL AL FINAL ---
        renderAgenda();
        lucide.createIcons();

        function formatPhoneNumber(phoneNumberString) {
            if (!phoneNumberString) return '';
            const cleaned = ('' + phoneNumberString).replace(/\D/g, '');
            const match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
            // Ensure US format: (XXX) XXX-XXXX
            return match ? `(${match[1]}) ${match[2]}-${match[3]}` : phoneNumberString;
        }
        
        function descargarComoCSV(data, filename) {
            const headers = Object.keys(data[0]);
            const csvRows = [headers.map(h => `"${h}"`).join(',')]; // Add quotes to headers
            for (const row of data) {
                const values = headers.map(header => {
                    const value = String(row[header] || '');
                    // Escape double quotes by doubling them, then wrap in double quotes
                    return `"${value.replace(/"/g, '""')}"`;
                });
                csvRows.push(values.join(','));
            }
            // Add BOM for proper UTF-8 encoding in Excel
            const blob = new Blob(["\uFEFF" + csvRows.join('\n')], { type: 'text/csv;charset=utf-8;' });
            const link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.download = filename;
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
        
        // --- FUNCIÓN NUEVA: Descargar como iCalendar (.ics) ---
        function descargarComoICS(data, filename) {
            if (!data || data.length === 0) {
                showToast('No hay datos para exportar a iCalendar.', 'info');
                return;
            }

            let icalContent = "BEGIN:VCALENDAR\r\n";
            icalContent += "VERSION:2.0\r\n";
            icalContent += "PRODID:-//Tu Negocio CRM//NONSGML Agenda//ES\r\n";
            icalContent += "CALSCALE:GREGORIAN\r\n";
            icalContent += "METHOD:PUBLISH\r\n";

            data.forEach(cita => {
                const startDate = new Date(cita.appointment_date + 'T' + cita.appointment_time);
                const endDate = new Date(startDate.getTime() + 60 * 60 * 1000); // Duración de 1 hora
                const dtStamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\..*Z/, 'Z');
                const dtStart = startDate.toISOString().replace(/[-:]/g, '').replace(/\..*Z/, 'Z');
                const dtEnd = endDate.toISOString().replace(/[-:]/g, '').replace(/\..*Z/, 'Z');
                
                icalContent += "BEGIN:VEVENT\r\n";
                icalContent += `UID:${cita.type}-${cita.id}@tu-negocio-crm.com\r\n`;
                icalContent += `DTSTAMP:${dtStamp}\r\n`;
                icalContent += `DTSTART:${dtStart}\r\n`;
                icalContent += `DTEND:${dtEnd}\r\n`;
                icalContent += `SUMMARY:Cita con ${cita.associated_entity_name}\r\n`;
                icalContent += `DESCRIPTION:Notas: ${cita.notes || 'N/A'}\r\n`;
                
                // Agrega la lógica de recurrencia si es una cita recurrente
                if (cita.type === 'recurrente' && cita.frequency) {
                    let rrule = '';
                    switch (cita.frequency) {
                        case 'weekly':
                            rrule = 'FREQ=WEEKLY';
                            break;
                        case 'bi-weekly':
                            rrule = 'FREQ=WEEKLY;INTERVAL=2';
                            break;
                        case 'monthly':
                            rrule = `FREQ=MONTHLY`;
                            // Agregamos la regla del día del mes
                            rrule += `;BYMONTHDAY=${startDate.getDate()}`;
                            break;
                    }
                    if (rrule) {
                        icalContent += `RRULE:${rrule}\r\n`;
                    }
                }
                
                // Recordatorio de 15 minutos antes de la cita
                icalContent += "BEGIN:VALARM\r\n";
                icalContent += "ACTION:DISPLAY\r\n";
                icalContent += "DESCRIPTION:Recordatorio de Cita\r\n";
                icalContent += "TRIGGER:-PT15M\r\n";
                icalContent += "END:VALARM\r\n";
                
                icalContent += "END:VEVENT\r\n";
            });

            icalContent += "END:VCALENDAR\r\n";
            
            const blob = new Blob([icalContent], { type: 'text/calendar;charset=utf-8' });
            const link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.download = filename;
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    });
</script>

</body>
</html>