<?php
// CARGA MAESTRA DE CONFIGURACIÓN Y BRANDING
require_once(__DIR__ . '/core/init.php'); // Carga $_SESSION['csrf_token']

$clients_data_from_db = [];
$db_error_message = null;
$prospects_data_for_autocomplete = [];
$available_services_data = [];
$months_with_clients_data = [];
$total_clients_count = 0;
$recurring_clients_count = 0;

// Saneamiento de entradas para filtros de fecha
$selected_year = isset($_GET['year']) ? filter_var($_GET['year'], FILTER_VALIDATE_INT) : (int)date('Y');
$selected_month = isset($_GET['month']) ? filter_var($_GET['month'], FILTER_VALIDATE_INT) : (int)date('m');

// Asegurar valores por defecto en caso de error de saneamiento
if ($selected_year === false || $selected_year < 1900 || $selected_year > 2100) $selected_year = (int)date('Y');
if ($selected_month === false || $selected_month < 1 || $selected_month > 12) $selected_month = (int)date('m');

$month_names_php = [1 => "ENERO", 2 => "FEBRERO", 3 => "MARZO", 4 => "ABRIL", 5 => "MAYO", 6 => "JUNIO", 7 => "JULIO", 8 => "AGOSTO", 9 => "SEPTIEMBRE", 10 => "OCTUBRE", 11 => "NOVIEMBRE", 12 => "DICIEMBRE"];
$display_month = isset($month_names_php[$selected_month]) ? $month_names_php[$selected_month] : 'MES DESCONOCIDO';
$initial_monthly_period_display = $display_month . ' ' . $selected_year;
$monthly_clients_count = 0;

/**
 * Crea la parte dinámica de la cláusula IN para consultas PDO.
 * @param array $ids Array de IDs a incluir.
 * @return string Una string de marcadores de posición (ej: "?, ?, ?").
 */
function create_in_clause(array $ids): string {
    if (empty($ids)) return '';
    return implode(',', array_fill(0, count($ids), '?'));
}

try { 

    // --- 1. OBTENCIÓN OPTIMIZADA DE CLIENTES ---
    $sql_clients = "
        SELECT 
            c.id, c.first_name, c.last_name, c.email, c.phone, c.mobile,
            c.street_address, c.city, c.state_province, c.zip_code, 
            c.created_at, c.is_recurring, c.access_code
        FROM clients c 
        ORDER BY c.created_at DESC";
    
    $stmt = $pdo->query($sql_clients);
    $raw_clients = $stmt->fetchAll(PDO::FETCH_ASSOC);

    $client_ids = array_column($raw_clients, 'id');
    
    $services_map = [];
    $counts_app = [];
    $counts_tasks = [];
    $counts_inv = [];
    $counts_est = [];
    $counts_complaints = [];

    if (!empty($client_ids)) {
        $in_clause = create_in_clause($client_ids);
        
        // 2. OBTENER SERVICIOS
        $sql_services = "
            SELECT cs.client_id, s.id as service_id, s.name as service_name
            FROM client_services cs
            JOIN services s ON cs.service_id = s.id
            WHERE cs.client_id IN ($in_clause)";
        $stmt_serv = $pdo->prepare($sql_services);
        $stmt_serv->execute($client_ids); 
        while ($row = $stmt_serv->fetch(PDO::FETCH_ASSOC)) {
            $services_map[$row['client_id']][] = $row;
        }

        // 3. OBTENER CONTEOS
        // Citas (unique_appointments)
        $sql_counts_app = "SELECT client_id, COUNT(*) as count FROM unique_appointments 
                            WHERE client_id IN ($in_clause) AND appointment_date >= CURDATE() AND status IN ('pending', 'confirmed') 
                            GROUP BY client_id";
        $stmt_counts_app = $pdo->prepare($sql_counts_app);
        $stmt_counts_app->execute($client_ids);
        $counts_app = $stmt_counts_app->fetchAll(PDO::FETCH_KEY_PAIR);
        
        // Tareas (tasks)
        $sql_counts_tasks = "SELECT client_id, COUNT(*) as count FROM tasks 
                            WHERE client_id IN ($in_clause) AND status = 'pending' 
                            GROUP BY client_id";
        $stmt_counts_tasks = $pdo->prepare($sql_counts_tasks);
        $stmt_counts_tasks->execute($client_ids);
        $counts_tasks = $stmt_counts_tasks->fetchAll(PDO::FETCH_KEY_PAIR);
        
        // Facturas (invoices)
        $sql_counts_inv = "SELECT client_id, COUNT(*) as count FROM invoices 
                        WHERE client_id IN ($in_clause) AND status IN ('pendiente', 'vencida', 'enviada', 'enviado') 
                        GROUP BY client_id";
        $stmt_counts_inv = $pdo->prepare($sql_counts_inv);
        $stmt_counts_inv->execute($client_ids);
        $counts_inv = $stmt_counts_inv->fetchAll(PDO::FETCH_KEY_PAIR);
        
        // Quotes (Cotizaciones) - CORREGIDO: Tabla 'quotes' y estados en Inglés según DB
        $sql_counts_est = "SELECT client_id, COUNT(*) as count FROM quotes 
                        WHERE client_id IN ($in_clause) AND status IN ('sent', 'approved', 'generated') 
                        GROUP BY client_id";
        $stmt_counts_est = $pdo->prepare($sql_counts_est);
        $stmt_counts_est->execute($client_ids);
        $counts_est = $stmt_counts_est->fetchAll(PDO::FETCH_KEY_PAIR);

        // Quejas (complaints)
        $sql_counts_complaints = "SELECT client_id, COUNT(*) as count FROM complaints 
                                     WHERE client_id IN ($in_clause) 
                                     AND status NOT IN ('Resuelto', 'Archivado') 
                                     GROUP BY client_id";
        $stmt_counts_complaints = $pdo->prepare($sql_counts_complaints);
        $stmt_counts_complaints->execute($client_ids);
        $counts_complaints = $stmt_counts_complaints->fetchAll(PDO::FETCH_KEY_PAIR);
    }

    // 4. ENSAMBLADO DE DATOS
    foreach ($raw_clients as $row) {
        $c_id = $row['id'];
        
        $my_services = isset($services_map[$c_id]) ? $services_map[$c_id] : [];
        $service_names = array_column($my_services, 'service_name');
        $service_ids = array_column($my_services, 'service_id');

        $clients_data_from_db[$c_id] = [
            'id' => $c_id,
            'nombre' => $row['first_name'],
            'apellido' => $row['last_name'],
            'email' => $row['email'],
            'phone' => $row['phone'],
            'mobile' => $row['mobile'],
            'servicios' => implode(', ', $service_names),
            'service_ids' => $service_ids,
            'direccion_calle' => $row['street_address'],
            'ciudad' => $row['city'],
            'state_province' => $row['state_province'],
            'zip_code' => $row['zip_code'],
            'created_at' => $row['created_at'],
            'is_recurring' => (bool)$row['is_recurring'],
            'access_code' => $row['access_code'],
            'upcoming_appointments' => isset($counts_app[$c_id]) ? (int)$counts_app[$c_id] : 0,
            'pending_tasks'         => isset($counts_tasks[$c_id]) ? (int)$counts_tasks[$c_id] : 0,
            'pending_invoices'      => isset($counts_inv[$c_id]) ? (int)$counts_inv[$c_id] : 0,
            'sent_estimates'        => isset($counts_est[$c_id]) ? (int)$counts_est[$c_id] : 0,
            'active_complaints'     => isset($counts_complaints[$c_id]) ? (int)$counts_complaints[$c_id] : 0
        ];
    }
    
    $total_clients_count = count($clients_data_from_db);
    $recurring_clients_count = count(array_filter($clients_data_from_db, function($client) { return $client['is_recurring']; }));

    // Cargar Prospectos (leads)
    $stmt_prospects = $pdo->query("SELECT id, first_name, last_name, company, email, phone, mobile, source, status, street_address, city, state_province, zip_code FROM leads ORDER BY id DESC");
    foreach ($stmt_prospects->fetchAll(PDO::FETCH_ASSOC) as $row) {
        $prospects_data_for_autocomplete[$row['id']] = $row;
    }

    // Cargar Servicios (services)
    $stmt_services = $pdo->query("SELECT id, name FROM services ORDER BY name ASC");
    $available_services_data = $stmt_services->fetchAll(PDO::FETCH_ASSOC);

    // Filtros Fecha
    $stmt_months = $pdo->query("SELECT DISTINCT YEAR(created_at) AS year, MONTH(created_at) AS month FROM clients ORDER BY year DESC, month DESC");
    $months_with_clients_data = $stmt_months->fetchAll(PDO::FETCH_ASSOC);

    // Conteo Mensual
    $stmt_monthly = $pdo->prepare("SELECT COUNT(id) AS count FROM clients WHERE YEAR(created_at) = :year AND MONTH(created_at) = :month");
    $stmt_monthly->execute([':year' => $selected_year, ':month' => $selected_month]);
    $monthly_clients_count = $stmt_monthly->fetchColumn();
    
} catch (PDOException $e) { 
    error_log("Error crítico DB: " . $e->getMessage());
    $db_error_message = 'Error al cargar datos. Contacte soporte.';
}

$clients_json = json_encode($clients_data_from_db, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE);
$prospects_json = json_encode($prospects_data_for_autocomplete, JSON_UNESCAPED_UNICODE);
$available_services_json = json_encode($available_services_data, JSON_UNESCAPED_UNICODE);
$months_with_clients_json = json_encode($months_with_clients_data);

function formatMoney($amount) {
    return '$' . number_format($amount, 2);
}

if (ob_get_level() > 0) {
    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>Centro De Clientes Empresariales <?php echo htmlspecialchars($branding['full_title']); ?></title>
    <meta name="robots" content="noindex, nofollow">
    
    <link rel="icon" type="image/png" href="<?php echo htmlspecialchars($branding['favicon'] ?? '/core/img/favicon.png'); ?>">
    <link rel="apple-touch-icon" href="<?php echo htmlspecialchars($branding['favicon'] ?? '/core/img/favicon.png'); ?>">
    
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="<?php echo htmlspecialchars($google_font_url ?? ''); ?>">

    <?php include 'files/gtm-head.php'; ?>
    
    <script src="https://unpkg.com/lucide@latest"></script>
    <link rel="stylesheet" href="style.css"> 
    <script src="files/header-manager.js"></script>

    <style>
        @keyframes blink-red-emergency {
            0%, 100% { border-color: rgba(220, 38, 38, 0.4); box-shadow: 0 0 0px rgba(220, 38, 38, 0); }
            50% { border-color: rgba(220, 38, 38, 1); box-shadow: 0 0 20px rgba(220, 38, 38, 0.6); }
        }
        .card-complaint-active {
            animation: blink-red-emergency 1.5s infinite ease-in-out;
            border-width: 2px !important;
        }
    </style>
</head>

<body
data-page-title="Centro De Clientes Empresariales"
data-page-subtitle="Control Informativo De Clientes Activos Del Negocio"
data-page-icon="user-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>
    
    <?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">

    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">

        <div class="stat-card bg-white p-3 lg:p-6 rounded-xl shadow-md flex items-center border-l-4 border-[var(--color-highlight)]">
            <i data-lucide="users" class="w-8 h-8 lg:w-12 lg:h-12 text-[var(--color-secondary)] shrink-0"></i>
            <div class="flex-1 flex justify-between items-center ml-3 lg:ml-4">
                <h3 class="text-md lg:text-lg font-black text-gray-500 leading-tight uppercase">TOTAL DE CLIENTES</h3>
                <p id="total-clients-count" class="text-5xl lg:text-5xl font-black text-[var(--color-primary)]"><?php echo $total_clients_count; ?></p>
            </div>
        </div>

        <div class="stat-card bg-white p-3 lg:p-6 rounded-xl shadow-md flex items-center border-l-4 border-[var(--color-highlight)]">
            <i data-lucide="repeat" class="w-8 h-8 lg:w-12 lg:h-12 text-[var(--color-secondary)] shrink-0"></i>
            <div class="flex-1 flex justify-between items-center ml-3 lg:ml-4">
                <h3 class="text-md lg:text-lg font-black text-gray-500 leading-tight uppercase">CLIENTES RECURRENTES</h3>
                <p id="recurring-clients-count" class="text-5xl lg:text-5xl font-black text-[var(--color-primary)]"><?php echo $recurring_clients_count; ?></p>
            </div>
        </div>

        <div class="stat-card bg-white p-3 lg:p-6 rounded-xl shadow-md flex items-center border-l-4 border-[var(--color-highlight)]">
            <i data-lucide="calendar" class="w-8 h-8 lg:w-12 lg:h-12 text-[var(--color-secondary)] shrink-0"></i>
            <div class="flex-1 flex justify-between items-center ml-3 lg:ml-4">
                <h3 class="text-md lg:text-lg font-black text-gray-500 leading-tight uppercase">CLIENTES ESTE MES</h3>
                <p id="monthly-clients-count" class="text-5xl lg:text-5xl font-black text-[var(--color-primary)]"><?php echo $monthly_clients_count; ?></p>
            </div>
        </div>

    </div>

    <section id="clientes" 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-black text-[var(--color-primary)] flex items-center gap-2">
                        <i data-lucide="user-check" class="w-7 h-7 text-[var(--color-secondary)]"></i> BASE DE DATOS DE CLIENTES
                    </h3>
                    <p class="text-gray-500 text-sm mt-1 uppercase">Ficha, actividad y servicios de cada cliente.</p>
                </div>
                <div class="flex flex-col md:flex-row items-center gap-4 w-full md:w-auto">
                    <button class="w-full bg-[var(--color-secondary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase sm:w-auto flex items-center justify-center gap-2" onclick="openPanel('addClientePanel')">
                        <i data-lucide="plus" class="w-5 h-5 mr-2"></i> AGREGAR CLIENTE
                    </button>
                    <button id="download-clientes-btn" class="w-full bg-[var(--color-primary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase sm:w-auto flex items-center justify-center gap-2">
                        <i data-lucide="download" class="w-4 h-4 mr-2"></i> DESCARGAR
                    </button>
                </div>
            </div>

            <div class="flex flex-col md:flex-row gap-4 mb-6 pt-4 border-t">
                <div class="relative flex-grow">
                    <input type="text" id="client-search" placeholder="Buscar Por Nombre..." 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="client-filter-type" class="w-full md:w-48 p-3 border border-gray-300 rounded-lg bg-white focus:ring-2 focus:ring-[var(--color-highlight)] outline-none uppercase">
                    <option value="all">TODOS LOS TIPOS</option>
                    <option value="recurring">RECURRENTES</option>
                    <option value="standard">ESTÁNDAR</option>
                </select>
                <select id="client-filter-apellido-letter" class="w-full md:w-48 p-3 border border-gray-300 rounded-lg bg-white uppercase focus:ring-2 focus:ring-[var(--color-highlight)] outline-none"></select>
                <select id="client-filter-service" class="w-full md:w-48 p-3 border border-gray-300 rounded-lg bg-white uppercase focus:ring-2 focus:ring-[var(--color-highlight)] outline-none"></select>
                <select id="monthly-filter-select" class="w-full md:w-64 p-3 border border-gray-300 rounded-lg bg-white uppercase focus:ring-2 focus:ring-[var(--color-highlight)] outline-none"></select>
                
                <div class="view-toggle inline-flex bg-gray-200 rounded-lg p-1">
                    <button id="grid-view-btn" class="px-3 py-1 rounded-md text-sm font-semibold active uppercase" title="Vista De Tarjetas">
                        <i data-lucide="layout-grid" class="w-5 h-5"></i>
                    </button>
                    <button id="list-view-btn" class="px-3 py-1 rounded-md text-sm font-semibold uppercase" title="Vista de Lista">
                        <i data-lucide="list" class="w-5 h-5"></i>
                    </button>
                </div>
            </div>
            <div id="client-grid-view" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"></div>
            <div id="client-list-view" class="overflow-x-auto hidden">
                <table class="min-w-full bg-white text-sm text-left responsive-table-stack">
                    <thead class="bg-gray-50 hidden md:table-header-group">
                        <tr class="text-left text-gray-500 uppercase text-sm">
                            <th class="py-3 px-6 font-semibold">Nombre</th>
                            <th class="py-3 px-6 font-semibold hidden md:table-cell">Contacto</th>
                            <th class="py-3 px-6 font-semibold">Servicios</th>
                            <th class="py-3 px-6 font-semibold">Actividad Pendiente</th>
                            <th class="py-3 px-6 font-semibold text-center">Acciones</th>
                        </tr>
                    </thead>
                    <tbody id="clientsTableBody"></tbody>
                </table>
            </div>
        </div>
    </section>
</div>
</main>
</div>

<div id="addClientePanel" class="fixed top-0 right-0 h-full w-full lg:w-1/3 bg-[var(--color-background)] z-50 transform translate-x-full transition-transform duration-300 ease-in-out shadow-2xl flex flex-col">
    <div class="flex flex-col h-full">
        <div class="flex-shrink-0 flex justify-between items-center p-4 border-b border-gray-200 bg-[var(--color-primary)] text-white shadow z-20">
            <h3 class="text-3xl font-black text-[var(--color-highlight)] flex items-center uppercase">
                <i data-lucide="user-plus" class="w-8 h-8 mr-2 text-white"></i> AGREGAR CLIENTE
            </h3>
            <button onclick="closePanel('addClientePanel')" class="bg-[var(--color-secondary)] text-white hover:text-[var(--color-highlight)] p-1 rounded-md transition-colors duration-200">
                <i data-lucide="x" class="w-8 h-8"></i>
            </button>
        </div>
        
        <div class="flex-grow overflow-y-auto p-4 space-y-6 relative">
            <div class="bg-white p-4 rounded-xl shadow-md transition duration-300">
                <div class="border-b pb-3 mb-4">
                    <h4 class="text-2xl font-black text-[var(--color-secondary)] uppercase flex items-center">
                        <i data-lucide="file-pen-line" class="w-5 h-5 mr-2"></i> DATOS DEL CLIENTE
                    </h4>
                </div>
                <form id="add-cliente-form" class="space-y-4">
                    <div class="relative bg-gray-50 p-3 rounded-lg border border-gray-200">
                        <label for="cliente-prospecto-search" class="block text-md font-bold text-gray-600 mb-1 uppercase">
                            <i data-lucide="search" class="w-4 h-4 inline mr-1"></i> Importar desde Prospecto
                        </label>
                        <input type="text" id="cliente-prospecto-search" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm" placeholder="Buscar Prospecto...">
                        <input type="hidden" id="cliente-selected-prospect-id">
                        <div id="prospect-search-results" class="absolute z-10 w-full bg-white border rounded-lg shadow-xl mt-1 max-h-60 overflow-y-auto hidden"></div>
                    </div>
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                            <label for="cliente-first-name" class="block text-md font-bold text-gray-600 mb-1 uppercase">Nombre</label>
                            <input type="text" id="cliente-first-name" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm" required>
                        </div>
                        <div>
                            <label for="cliente-last-name" class="block text-md font-bold text-gray-600 mb-1 uppercase">Apellido</label>
                            <input type="text" id="cliente-last-name" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                    </div>
                    <div>
                        <label for="cliente-email" class="block text-md font-bold text-gray-600 mb-1 uppercase">Email</label>
                        <input type="email" id="cliente-email" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                    </div>
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                            <label for="cliente-phone" class="block text-md font-bold text-gray-600 mb-1 uppercase">Teléfono Fijo</label>
                            <input type="tel" id="cliente-phone" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                        <div>
                            <label for="cliente-mobile" class="block text-md font-bold text-gray-600 mb-1 uppercase">Celular</label>
                            <input type="tel" id="cliente-mobile" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                    </div>
                    <div>
                        <label for="cliente-servicio-search" class="block text-md font-bold text-gray-600 mb-1 uppercase">Añadir Servicio</label>
                        <div class="relative">
                            <input type="text" id="cliente-servicio-search" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm" placeholder="Buscar Servicio...">
                            <div id="service-search-results" class="absolute z-10 w-full bg-white border rounded-lg shadow-xl mt-1 max-h-40 overflow-y-auto hidden"></div>
                        </div>
                        <div id="selected-services-container" class="mt-2 flex flex-wrap gap-2"></div>
                        <input type="hidden" id="cliente-servicios">
                    </div>
                    <div class="flex items-center bg-[var(--color-secondary)] p-2 rounded-lg border border-gray-200">
                        <input type="checkbox" id="cliente-is-recurring" class="h-5 w-5 text-[var(--color-primary)] border-gray-300 rounded mr-2 focus:ring-[var(--color-highlight)]">
                        <label for="cliente-is-recurring" class="text-white text-sm font-black uppercase">Cliente Recurrente</label>
                    </div>
                    <div class="border-t pt-4">
                        <label for="cliente-direccion-calle" class="block text-md font-bold text-gray-600 mb-1 uppercase">Dirección</label>
                        <input type="text" id="cliente-direccion-calle" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                    </div>
                    <div class="grid grid-cols-3 gap-3">
                        <div class="col-span-1">
                            <label for="cliente-ciudad" class="block text-md font-bold text-gray-600 mb-1 uppercase">Ciudad</label>
                            <input type="text" id="cliente-ciudad" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                        <div class="col-span-1">
                            <label for="cliente-estado-field" class="block text-md font-bold text-gray-600 mb-1 uppercase">Estado</label>
                            <input type="text" id="cliente-estado-field" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                        <div class="col-span-1">
                            <label for="cliente-codigo-postal" class="block text-md font-bold text-gray-600 mb-1 uppercase">ZIP CODE</label>
                            <input type="text" id="cliente-codigo-postal" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                    </div>
                </form>
            </div>
        </div>
        
        <div class="p-4 bg-gray-100 border-t border-gray-200 flex-shrink-0 z-10">
            <div class="grid grid-cols-2 gap-3">
                <button type="button" class="w-full bg-[var(--color-secondary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase w-full sm:w-auto flex items-center justify-center gap-2" onclick="closePanel('addClientePanel')">
                    <i data-lucide="x-circle" class="w-5 h-5"></i> CANCELAR
                </button>
                <button type="submit" form="add-cliente-form" class="w-full bg-[var(--color-primary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase w-full sm:w-auto flex items-center justify-center gap-2">
                    <i data-lucide="save" class="w-5 h-5"></i> GUARDAR
                </button>
            </div>
        </div>
    </div>
</div>

<div id="viewClienteReadOnlyPanel" class="fixed top-0 right-0 h-full w-full lg:w-1/3 bg-[var(--color-background)] z-50 transform translate-x-full transition-transform duration-300 ease-in-out shadow-2xl flex flex-col">
    <div class="flex flex-col h-full">
        <div class="flex-shrink-0 flex justify-between items-center p-4 border-b border-gray-200 bg-[var(--color-primary)] text-white shadow z-20">
            <h3 class="text-3xl font-black text-[var(--color-highlight)] flex items-center uppercase">
                <i data-lucide="user-circle" class="w-8 h-8 mr-2 text-white"></i> FICHA DEL CLIENTE
            </h3>
            <button onclick="closePanel('viewClienteReadOnlyPanel')" class="bg-[var(--color-secondary)] text-white hover:text-[var(--color-highlight)] p-1 rounded-md transition-colors duration-200">
                <i data-lucide="x" class="w-8 h-8"></i>
            </button>
        </div>
        
        <div class="flex-grow overflow-y-auto p-4 space-y-6 relative">
            <div class="bg-white p-4 rounded-xl shadow-md transition duration-300 space-y-6">
                <div class="text-center border-b pb-4">
                    <h2 id="readonly-cliente-full-name" class="text-3xl font-black text-gray-800 uppercase"></h2>
                    <div id="readonly-cliente-recurring-tag" class="mt-2 hidden">
                        <span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-bold bg-purple-100 text-purple-800 uppercase border border-purple-200">
                            <i data-lucide="repeat" class="w-4 h-4 mr-1"></i> Cliente Recurrente
                        </span>
                    </div>
                </div>
                <div>
                    <h3 class="text-lg font-black text-[var(--color-primary)] mb-3 flex items-center uppercase border-b border-gray-100 pb-1">
                        <i data-lucide="contact" class="w-5 h-5 mr-2"></i> Información De Contacto
                    </h3>
                    <div class="space-y-3 pl-2">
                        <div id="readonly-cliente-email-group" class="flex items-center text-gray-700">
                            <i data-lucide="mail" class="w-4 h-4 text-[var(--color-primary)] mr-3"></i>
                            <p id="readonly-cliente-email" class="font-medium text-sm break-all"></p>
                        </div>
                        <div id="readonly-cliente-phone-group" class="flex items-center text-gray-700">
                            <i data-lucide="phone" class="w-4 h-4 text-[var(--color-primary)] mr-3"></i>
                            <p id="readonly-cliente-phone" class="font-medium text-sm"></p>
                        </div>
                        <div id="readonly-cliente-mobile-group" class="flex items-center text-gray-700">
                            <i data-lucide="smartphone" class="w-4 h-4 text-[var(--color-primary)] mr-3"></i>
                            <p id="readonly-cliente-mobile" class="font-medium text-sm"></p>
                        </div>
                        <div id="readonly-cliente-address-group" class="flex items-start text-gray-700">
                            <i data-lucide="map-pin" class="w-4 h-4 text-[var(--color-primary)] mr-3 mt-1"></i>
                            <p id="readonly-cliente-full-address" class="font-medium text-sm"></p>
                        </div>
                    </div>
                </div>
                <div class="bg-blue-50 border border-blue-100 p-4 rounded-lg">
                    <h3 class="text-2xl font-black text-[var(--color-primary)] mb-1 uppercase flex items-center">
                        <i data-lucide="globe" class="w-4 h-4 mr-2"></i> Portal del Cliente VIP
                    </h3>
                    <p class="text-xs text-blue-600 mb-3 font-semibold uppercase">Código de acceso único.</p>
                    <div class="relative bg-white p-2 rounded-md shadow-sm border border-blue-100">
                        <input type="password" id="readonly-access-code" class="w-full font-mono text-lg text-gray-700 bg-transparent border-none focus:ring-0 p-0 pr-36" readonly>
                        <div class="absolute inset-y-0 right-0 flex items-center pr-1 gap-1">
                            <button id="toggle-access-code-btn" class="p-1.5 text-gray-500 hover:bg-gray-100 rounded-md" title="Mostrar/Ocultar"><i data-lucide="eye" class="w-4 h-4"></i></button>
                            <button id="copy-access-code-btn" class="p-1.5 text-gray-500 hover:bg-gray-100 rounded-md" title="Copiar"><i data-lucide="copy" class="w-4 h-4"></i></button>
                            <button id="generate-access-code-btn" class="p-1.5 text-green-600 hover:bg-green-100 rounded-md" title="Generar"><i data-lucide="refresh-cw" class="w-4 h-4"></i></button>
                            <button id="delete-access-code-btn" class="p-1.5 text-red-500 hover:bg-red-100 rounded-md" title="Eliminar"><i data-lucide="trash-2" class="w-4 h-4"></i></button>
                        </div>
                    </div>
                </div>
                <div>
                    <h3 class="text-lg font-black text-[var(--color-primary)] mb-3 flex items-center uppercase border-b border-gray-100 pb-1">
                        <i data-lucide="package" class="w-5 h-5 mr-2"></i> Servicios Asociados
                    </h3>
                    <div id="readonly-cliente-services-display" class="flex flex-wrap gap-2"></div>
                </div>
                <div class="border-t pt-4">
                    <h3 class="text-2xl font-black text-[var(--color-primary)] mb-3 uppercase flex items-center">
                        <i data-lucide="activity" class="w-5 h-5 mr-2"></i> Actividad Generadas
                    </h3>
                    <div class="grid grid-cols-4 gap-2 mb-4">
                        <button onclick="switchTab('tab-invoices')" class="tab-btn p-2 rounded text-md md:text-xs font-black uppercase transition-colors active-tab bg-[var(--color-primary)] text-white" data-target="tab-invoices">Facturas</button>
                        <button onclick="switchTab('tab-appointments')" class="tab-btn bg-gray-100 p-2 rounded text-md md:text-xs font-black hover:bg-[var(--color-highlight)] hover:text-black uppercase transition-colors" data-target="tab-appointments">Citas</button>
                        <button onclick="switchTab('tab-tasks')" class="tab-btn bg-gray-100 p-2 rounded text-md md:text-xs font-black hover:bg-[var(--color-highlight)] hover:text-black uppercase transition-colors" data-target="tab-tasks">Tareas</button>
                        <button onclick="switchTab('tab-estimates')" class="tab-btn bg-gray-100 p-2 rounded text-md md:text-xs font-black hover:bg-[var(--color-highlight)] hover:text-black uppercase transition-colors" data-target="tab-estimates">Estimados</button>
                    </div>
                    <div id="tab-invoices" class="tab-content space-y-2 max-h-48 overflow-y-auto custom-scrollbar bg-gray-50 p-2 rounded border border-gray-100">
                        <div id="readonly-invoices-list" class="text-xs text-gray-500 font-medium">Cargando...</div>
                    </div>
                    <div id="tab-appointments" class="tab-content hidden space-y-2 max-h-48 overflow-y-auto custom-scrollbar bg-gray-50 p-2 rounded border border-gray-100">
                        <div id="readonly-appointments-list" class="text-xs text-gray-500 font-medium">Cargando...</div>
                    </div>
                    <div id="tab-tasks" class="tab-content hidden space-y-2 max-h-48 overflow-y-auto custom-scrollbar bg-gray-50 p-2 rounded border border-gray-100">
                        <div id="readonly-tasks-list" class="text-xs text-gray-500 font-medium">Cargando...</div>
                    </div>
                    <div id="tab-estimates" class="tab-content hidden space-y-2 max-h-48 overflow-y-auto custom-scrollbar bg-gray-50 p-2 rounded border border-gray-100">
                        <div id="readonly-estimates-list" class="text-xs text-gray-500 font-medium">Cargando...</div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="p-4 bg-gray-100 border-t border-gray-200 flex-shrink-0 z-10">
            <div class="grid grid-cols-2 gap-3">
                <button type="button" class="w-full bg-[var(--color-primary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase w-full sm:w-auto flex items-center justify-center gap-2" onclick="closePanel('viewClienteReadOnlyPanel')">
                    <i data-lucide="x-circle" class="w-5 h-5"></i> CERRAR
                </button>
                <button type="button" class="w-full bg-[var(--color-secondary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase w-full sm:w-auto flex items-center justify-center gap-2" id="edit-client-from-readonly-btn">
                    <i data-lucide="edit" class="w-5 h-5"></i> EDITAR
                </button>
            </div>
        </div>
    </div>
</div>

<div id="viewClientePanel" class="fixed top-0 right-0 h-full w-full lg:w-1/3 bg-[var(--color-background)] z-50 transform translate-x-full transition-transform duration-300 ease-in-out shadow-2xl flex flex-col">
    <div class="flex flex-col h-full">
        <div class="flex-shrink-0 flex justify-between items-center p-4 border-b border-gray-200 bg-[var(--color-primary)] text-white shadow z-20">
            <h3 class="text-3xl font-black text-[var(--color-highlight)] flex items-center uppercase">
                <i data-lucide="user-cog" class="w-8 h-8 mr-2 text-white"></i> EDITAR CLIENTE
            </h3>
            <button onclick="closePanel('viewClientePanel')" class="bg-[var(--color-secondary)] text-white hover:text-[var(--color-highlight)] p-1 rounded-md transition-colors duration-200">
                <i data-lucide="x" class="w-8 h-8"></i>
            </button>
        </div>
        
        <div class="flex-grow overflow-y-auto p-4 space-y-6 relative">
            <div class="bg-white p-4 rounded-xl shadow-md transition duration-300">
                <div class="border-b pb-3 mb-4">
                    <h4 class="text-2xl font-black text-[var(--color-secondary)] uppercase flex items-center">
                        <i data-lucide="edit" class="w-5 h-5 mr-2"></i> MODIFICAR DATOS
                    </h4>
                </div>
                <form id="view-cliente-form" class="space-y-4">
                    <input type="hidden" id="view-cliente-id">
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                            <label for="view-cliente-first-name" class="block text-md font-bold text-gray-600 mb-1 uppercase">Nombre</label>
                            <input type="text" id="view-cliente-first-name" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                        <div>
                            <label for="view-cliente-last-name" class="block text-md font-bold text-gray-600 mb-1 uppercase">Apellido</label>
                            <input type="text" id="view-cliente-last-name" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                    </div>
                    <div>
                        <label for="view-cliente-email" class="block text-md font-bold text-gray-600 mb-1 uppercase">Email</label>
                        <input type="email" id="view-cliente-email" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                    </div>
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                            <label for="view-cliente-phone" class="block text-md font-bold text-gray-600 mb-1 uppercase">Teléfono Fijo</label>
                            <input type="tel" id="view-cliente-phone" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                        <div>
                            <label for="view-cliente-mobile" class="block text-md font-bold text-gray-600 mb-1 uppercase">Celular</label>
                            <input type="tel" id="view-cliente-mobile" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                    </div>
                    <div>
                        <label for="view-cliente-servicio-search" class="block text-md font-bold text-gray-600 mb-1 uppercase">Editar Servicios</label>
                        <div class="relative">
                            <input type="text" id="view-cliente-servicio-search" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm" placeholder="Buscar Servicio...">
                            <div id="view-service-search-results" class="absolute z-10 w-full bg-white border mt-1 rounded-lg shadow-xl max-h-40 overflow-y-auto hidden"></div>
                        </div>
                        <div id="view-selected-services-container" class="mt-2 flex flex-wrap gap-2"></div>
                        <input type="hidden" id="view-cliente-servicios">
                    </div>
                    <div class="flex items-center bg-gray-50 p-2 rounded-lg border border-gray-200">
                        <input type="checkbox" id="view-cliente-is-recurring" class="h-5 w-5 text-[var(--color-primary)] border-gray-300 rounded mr-2 focus:ring-[var(--color-highlight)]">
                        <label for="view-cliente-is-recurring" class="text-gray-700 text-sm font-bold uppercase">Cliente Recurrente</label>
                    </div>
                    <div class="border-t pt-4">
                        <label for="view-cliente-direccion-calle" class="block text-md font-bold text-gray-600 mb-1 uppercase">Dirección</label>
                        <input type="text" id="view-cliente-direccion-calle" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                    </div>
                    <div class="grid grid-cols-3 gap-3">
                        <div class="col-span-1">
                            <label for="view-cliente-ciudad" class="block text-md font-bold text-gray-600 mb-1 uppercase">Ciudad</label>
                            <input type="text" id="view-cliente-ciudad" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                        <div class="col-span-1">
                            <label for="view-cliente-estado-field" class="block text-md font-bold text-gray-600 mb-1 uppercase">Estado</label>
                            <input type="text" id="view-cliente-estado-field" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                        <div class="col-span-1">
                            <label for="view-cliente-codigo-postal" class="block text-md font-bold text-gray-600 mb-1 uppercase">ZIP CODE</label>
                            <input type="text" id="view-cliente-codigo-postal" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-highlight)] focus:ring-[var(--color-highlight)] focus:ring-1 transition duration-150 text-sm">
                        </div>
                    </div>
                </form>
            </div>
        </div>
        
        <div class="p-4 bg-gray-100 border-t border-gray-200 flex-shrink-0 z-10">
            <div class="grid grid-cols-2 gap-3">
                <button type="button" class="w-full bg-[var(--color-secondary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase w-full sm:w-auto flex items-center justify-center gap-2" onclick="closePanel('viewClientePanel')">
                    <i data-lucide="x-circle" class="w-5 h-5"></i> CANCELAR
                </button>
                <button type="submit" form="view-cliente-form" class="w-full bg-[var(--color-primary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase w-full sm:w-auto flex items-center justify-center gap-2">
                    <i data-lucide="save" class="w-5 h-5"></i> ACTUALIZAR
                </button>
            </div>
        </div>
    </div>
</div>

<div id="confirmGenerateCodeModal" class="fixed inset-0 bg-gray-900 bg-opacity-90 flex items-center justify-center hidden z-50" onclick="if(event.target === this) closeModal('confirmGenerateCodeModal')">
    <div class="bg-white rounded-xl shadow-2xl w-full max-w-sm m-4 transform transition-all duration-300 scale-95 opacity-0 text-center">
        <div class="modal-header-container rounded-t-xl pt-6">
            <h3 class="modal-primary-title text-4xl font-black text-[var(--color-highlight)] uppercase leading-none">ADVERTENCIA</h3>
        </div>
        <div class="p-8">
            <div class="flex justify-center mb-6">
                <i id="generate-code-modal-icon" data-lucide="refresh-cw" class="w-16 h-16 text-[var(--color-primary)]"></i>
            </div>
            <p class="text-[var(--color-primary)] mb-6 uppercase text-lg font-bold leading-tight">
                <span id="generate-code-modal-message">¿GENERAR NUEVO CÓDIGO DE ACCESO PARA</span>
                <span id="generate-code-item-name" class="font-black text-[var(--color-secondary)] text-lg uppercase"></span>
            </p>
            <div class="flex flex-col sm:flex-row justify-center space-y-2 sm:space-y-0 sm:space-x-4">
                <button type="button" class="w-full bg-[var(--color-secondary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase sm:w-auto flex items-center justify-center gap-2" onclick="closeModal('confirmGenerateCodeModal')">
                    <i data-lucide="x-circle" class="w-5 h-5"></i> CANCELAR
                </button>
                <button type="button" class="w-full bg-[var(--color-primary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase sm:w-auto flex items-center justify-center gap-2" id="confirm-generate-code-button">
                    <i data-lucide="refresh-cw" class="w-5 h-5"></i> GENERAR
                </button>
            </div>
            <p class="mt-6 uppercase text-xs font-black text-gray-500 tracking-wider">EL CÓDIGO ANTERIOR SERÁ REEMPLAZADO PERMANENTEMENTE</p>
        </div>
    </div>
</div>

<div id="confirmDeleteModal" class="fixed inset-0 bg-gray-900 bg-opacity-90 flex items-center justify-center hidden z-50" onclick="if(event.target === this) closeModal('confirmDeleteModal')">
    <div class="bg-white rounded-xl shadow-2xl w-full max-w-sm m-4 transform transition-all duration-300 scale-95 opacity-0 text-center">
        <div class="modal-header-container rounded-t-xl pt-6">
            <h3 class="modal-primary-title text-4xl font-black text-[var(--color-highlight)] uppercase leading-none">ADVERTENCIA</h3>
        </div>
        <div class="p-8">
            <div class="flex justify-center mb-6">
                <i id="confirm-modal-icon" data-lucide="alert-triangle" class="w-16 h-16 text-[var(--color-secondary)]"></i>
            </div>
            <p class="text-[var(--color-primary)] mb-6 uppercase text-lg font-bold leading-tight">
                <span id="confirm-modal-message">¿CONFIRMAS LA ELIMINACIÓN DEL CLIENTE </span>
                <span id="delete-item-name" class="font-black text-[var(--color-secondary)] text-lg uppercase"></span>
            </p>
            <div class="flex flex-col sm:flex-row justify-center space-y-2 sm:space-y-0 sm:space-x-4">
                <button type="button" class="w-full bg-[var(--color-primary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase w-full sm:w-auto flex items-center justify-center gap-2" onclick="closeModal('confirmDeleteModal')">
                    <i data-lucide="x-circle" class="w-5 h-5"></i> CANCELAR
                </button>
                <button type="button" class="w-full bg-[var(--color-secondary)] hover:opacity-90 text-white font-black py-2.5 px-4 rounded-lg uppercase w-full sm:w-auto flex items-center justify-center gap-2" id="confirm-delete-button">
                    <i data-lucide="trash-2" class="w-5 h-5"></i> ELIMINAR
                </button>
            </div>
            <p class="mt-6 uppercase text-xs font-black text-gray-500 tracking-wider">ESTA ACCIÓN NO SE PUEDE DESHACER</p>
        </div>
    </div>
</div>

<script>
    let clientsFromDB = <?php echo $clients_json; ?>;
    let prospectsFromDB = <?php echo $prospects_json; ?>;
    let availableServices = <?php echo $available_services_json; ?>;
    const monthsWithClients = <?php echo $months_with_clients_json; ?>;
    let selectedMonth = <?php echo $selected_month; ?>;
    let selectedYear = <?php echo $selected_year; ?>;

    let currentClientView = 'grid';
    let selectedServiceIds = new Set();
    let viewSelectedServiceIds = new Set();
    let currentReadOnlyClientId = null;
    
    // --- Panel & Modal Management ---
    const panelOverlay = document.createElement('div');
    panelOverlay.className = 'fixed inset-0 bg-gray-900 bg-opacity-75 z-40 hidden';
    document.body.appendChild(panelOverlay);

    window.openPanel = (panelId) => {
        const panel = document.getElementById(panelId);
        if (!panel) return;
        if (panelId === 'addClientePanel') {
            document.getElementById('add-cliente-form').reset();
            selectedServiceIds.clear();
            renderSelectedServices(selectedServiceIds, document.getElementById('selected-services-container'), document.getElementById('cliente-servicios'));
        }
        panel.classList.remove('translate-x-full');
        panelOverlay.classList.remove('hidden');
        if(typeof lucide !== 'undefined') lucide.createIcons();
    };

    window.closePanel = (panelId) => {
        document.getElementById(panelId)?.classList.add('translate-x-full');
        const anyPanelOpen = Array.from(document.querySelectorAll('.fixed.inset-y-0')).some(p => !p.classList.contains('translate-x-full'));
        if (!anyPanelOpen) panelOverlay.classList.add('hidden');
    };
    
    window.openModal = (modalId) => {
        const modal = document.getElementById(modalId);
        if (!modal) return;
        const modalContent = modal.querySelector('div:first-child');
        modal.classList.remove('hidden');
        setTimeout(() => modalContent.classList.remove('scale-95', 'opacity-0'), 50);
        panelOverlay.classList.remove('hidden');
        if(typeof lucide !== 'undefined') lucide.createIcons();
    };

    window.closeModal = (modalId) => {
        const modal = document.getElementById(modalId);
        if (!modal) return;
        const modalContent = modal.querySelector('div:first-child');
        modalContent.classList.add('scale-95', 'opacity-0');
        setTimeout(() => {
            modal.classList.add('hidden');
            const anyPanelOpen = Array.from(document.querySelectorAll('.fixed.inset-y-0')).some(p => !p.classList.contains('translate-x-full'));
            if (!anyPanelOpen) panelOverlay.classList.add('hidden');
        }, 300);
    };

    const openConfirmationModal = (messagePrefix, itemName, confirmAction, icon = 'alert-triangle', iconColor = 'text-[var(--color-secondary)]') => {
        document.getElementById('confirm-modal-message').textContent = messagePrefix;
        document.getElementById('delete-item-name').textContent = itemName;
        const modalIcon = document.getElementById('confirm-modal-icon');
        modalIcon.setAttribute('data-lucide', icon);
        modalIcon.className = `w-16 h-16 ${iconColor}`;
        document.getElementById('confirm-delete-button').onclick = () => {
            const deleteBtn = document.getElementById('confirm-delete-button');
            deleteBtn.disabled = true;
            deleteBtn.innerHTML = '<i data-lucide="loader-2" class="w-5 h-5 mr-2 animate-spin"></i> PROCESANDO';
            if(typeof lucide !== 'undefined') lucide.createIcons();
            confirmAction(deleteBtn); // Pasa el botón a la acción para resetearlo si hay error
        };
        openModal('confirmDeleteModal');
    };

    const openGenerateCodeModal = (messagePrefix, itemName, confirmAction, icon = 'refresh-cw', iconColor = 'text-[var(--color-primary)]') => {
        document.getElementById('generate-code-modal-message').textContent = messagePrefix;
        document.getElementById('generate-code-item-name').textContent = itemName ? itemName.toUpperCase() : '';
        const modalIcon = document.getElementById('generate-code-modal-icon');
        modalIcon.setAttribute('data-lucide', icon);
        modalIcon.className = `w-16 h-16 ${iconColor}`;
        document.getElementById('confirm-generate-code-button').onclick = () => {
            const generateBtn = document.getElementById('confirm-generate-code-button');
            generateBtn.disabled = true;
            generateBtn.innerHTML = '<i data-lucide="loader-2" class="w-5 h-5 mr-2 animate-spin"></i> GENERANDO...';
            if(typeof lucide !== 'undefined') lucide.createIcons();
            confirmAction(generateBtn);
        };
        openModal('confirmGenerateCodeModal');
    };

    panelOverlay.addEventListener('click', () => {
        closePanel('addClientePanel');
        closePanel('viewClientePanel');
        closePanel('viewClienteReadOnlyPanel');
        closeModal('confirmDeleteModal');
        closeModal('confirmGenerateCodeModal'); 
    });

    const getServiceTagColors = (serviceName) => {
        const serviceTagColors = ['blue', 'green', 'purple', 'yellow', 'pink', 'indigo', 'red', 'gray'].map(c => ({ bg: `bg-${c}-100`, text: `text-${c}-800` }));
        let hash = 0;
        for (let i = 0; i < (serviceName || '').length; i++) { hash = serviceName.charCodeAt(i) + ((hash << 5) - hash); }
        return serviceTagColors[Math.abs(hash) % serviceTagColors.length];
    };
    
    const formatPhoneNumber = (value) => {
        if (!value) return '';
        const cleaned = ('' + value).replace(/\D/g, '');
        const match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
        return match ? `(${match[1]}) ${match[2]}-${match[3]}` : value;
    };

    window.switchTab = (tabId) => {
        document.querySelectorAll('.tab-content').forEach(el => el.classList.add('hidden'));
        document.querySelectorAll('.tab-btn').forEach(el => {
            el.classList.remove('active-tab', 'bg-[var(--color-primary)]', 'text-white');
            el.classList.add('bg-gray-100', 'text-gray-800');
        });
        document.getElementById(tabId).classList.remove('hidden');
        const activeBtn = document.querySelector(`button[data-target="${tabId}"]`);
        if(activeBtn) {
            activeBtn.classList.remove('bg-gray-100', 'text-gray-800');
            activeBtn.classList.add('active-tab', 'bg-[var(--color-primary)]', 'text-white');
        }
        if(typeof lucide !== 'undefined') lucide.createIcons();
    };
    
    // --- 1. MEJORA VISUAL DEL RESUMEN DE ACTIVIDAD (Acentos con var(--color-highlight)) ---
    const renderActivitySummary = (client, isCompact = false) => {
        const items = [
            { icon: 'calendar', count: client.upcoming_appointments, label: 'Citas' },
            { icon: 'check-square', count: client.pending_tasks, label: 'Tareas' },
            { icon: 'file-text', count: client.pending_invoices, label: 'Facturas' },
            { icon: 'file-bar-chart-2', count: client.sent_estimates, label: 'Quotes' }
        ];

        if (isCompact) {
            // Vista para la tabla (Compacta)
            const pendingItems = items.filter(item => item.count > 0);
            if (pendingItems.length === 0) return '<span class="text-xs text-gray-400 opacity-70">Sin pendientes</span>';
            // Usamos el color de destaque para los badges pendientes en la lista.
            return `<div class="flex items-center gap-2 flex-wrap">${pendingItems.map(item => `
                <div class="flex items-center gap-1.5 text-[10px] font-bold text-[var(--color-primary)] bg-[var(--color-highlight)] px-2 py-0.5 rounded-full" title="${item.count} ${item.label} pendiente(s)">
                    <i data-lucide="${item.icon}" class="w-3 h-3"></i><span>${item.count}</span>
                </div>`).join('')}</div>`;
        }
        
        return `<div class="grid grid-cols-2 gap-3 w-full mt-5">
            ${items.map(item => {
                const activeClass = item.count > 0 
                    ? 'bg-[var(--color-highlight)] text-[var(--color-primary)] border-[var(--color-highlight)] ring-1 ring-white' 
                    : 'bg-white/10 text-white/70 border-white/20';
                
                const iconClass = item.count > 0 ? 'text-[var(--color-primary)]' : 'text-white/50';

                return `
                <div class="flex items-center justify-between px-3 py-2 rounded-lg border transition-colors duration-200 ${activeClass}">
                    <div class="flex items-center gap-2">
                        <i data-lucide="${item.icon}" class="w-4 h-4 ${iconClass}"></i>
                        <span class="text-xs font-semibold uppercase tracking-wide">${item.label}</span>
                    </div>
                    <span class="text-sm font-black">${item.count}</span>
                </div>`;
            }).join('')}
        </div>`;
    };


    // --- 2. TARJETA DE CLIENTE CON COLORES DE BRANDING ---
    const renderClientCard = (client) => {
        const fullName = `${client.nombre || ''} ${client.apellido || ''}`.trim();
        const initial = (client.nombre || 'C').charAt(0).toUpperCase();

        let cardBgClass, textMainClass, textSubClass, ringClass, buttonClass, badgeBgClass, badgeTextClass;

        if (client.is_recurring) {
            // --- CLIENTE RECURRENTE ---
            cardBgClass = 'bg-black border-red-800'; 
            textMainClass = 'text-white';
            textSubClass = 'text-red-100/80';
            ringClass = 'ring-white/30 text-[var(--color-secondary)] bg-white';
            buttonClass = 'bg-white text-[var(--color-secondary)] hover:bg-gray-100';
            badgeBgClass = 'bg-white/10 text-white border-white/20';
            badgeTextClass = 'text-white';
        } else {
            // --- CLIENTE ESTÁNDAR ---
            cardBgClass = 'bg-[var(--color-primary)] border-blue-800';
            textMainClass = 'text-white';
            textSubClass = 'text-blue-100/80';
            ringClass = 'ring-white/30 text-[var(--color-primary)] bg-white';
            buttonClass = 'bg-[var(--color-highlight)] text-[var(--color-primary)] hover:opacity-90';
            badgeBgClass = 'bg-white/10 text-white border-white/20';
            badgeTextClass = 'text-white';
        }

        // --- ALERTA DE COMPLAINT (MODIFICADA: Ahora parpadea la tarjeta) ---
        const complaintClass = client.active_complaints > 0 ? 'card-complaint-active' : '';

        const servicesHtml = client.servicios 
            ? client.servicios.split(', ').slice(0, 3).map(s => 
                `<span class="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-wider ${badgeBgClass} ${badgeTextClass} border mr-1 mb-1">
                    ${s}
                </span>`
              ).join('') + (client.servicios.split(', ').length > 3 ? `<span class="text-[10px] ${textSubClass} ml-1">...</span>` : '')
            : `<p class="${textSubClass} text-xs italic font-medium flex items-center justify-center gap-1"><i data-lucide="minus-circle" class="w-3 h-3"></i> Sin servicios activos</p>`;

        const recurringBadge = client.is_recurring 
            ? `<div class="absolute top-3 right-3 z-10">
                <span class="inline-flex items-center px-2 py-1 rounded-md text-[10px] uppercase tracking-wide bg-white text-[var(--color-secondary)] border border-white/50 shadow-sm font-black">
                    <i data-lucide="repeat" class="w-3 h-3 mr-1"></i> RECURRENTE
                </span>
               </div>` 
            : '';
        
        const renderDarkActivitySummary = (c) => {
            const items = [
                { icon: 'calendar', count: c.upcoming_appointments, label: 'Citas' },
                { icon: 'check-square', count: c.pending_tasks, label: 'Tareas' },
                { icon: 'file-text', count: c.pending_invoices, label: 'Facturas' },
                { icon: 'file-bar-chart-2', count: c.sent_estimates, label: 'Quotes' }
            ];
            
            let activeBg, activeText, inactiveBg, inactiveText, inactiveIcon;
            if (client.is_recurring) { 
                activeBg = 'bg-white'; activeText = 'text-[var(--color-secondary)]';
                inactiveBg = 'bg-white/10'; inactiveText = 'text-white/70'; inactiveIcon = 'text-white/50';
            } else { 
                activeBg = 'bg-[var(--color-highlight)]'; activeText = 'text-[var(--color-primary)]';
                inactiveBg = 'bg-white/10'; inactiveText = 'text-white/70'; inactiveIcon = 'text-white/50';
            }
            
            return `<div class="grid grid-cols-2 gap-3 w-full mt-5">
            ${items.map(item => {
                const classes = item.count > 0 
                    ? `${activeBg} ${activeText} font-black border-none`
                    : `${inactiveBg} ${inactiveText} border-white/20 font-medium`;
                const iconClasses = item.count > 0 ? activeText : inactiveIcon;
                
                return `
                <div class="flex items-center justify-between px-3 py-2 rounded-lg border transition-colors duration-200 ${classes}">
                    <div class="flex items-center gap-2">
                        <i data-lucide="${item.icon}" class="w-4 h-4 ${iconClasses}"></i>
                        <span class="text-xs font-semibold uppercase tracking-wide">${item.label}</span>
                    </div>
                    <span class="text-sm font-black">${item.count}</span>
                </div>`;
            }).join('')}
            </div>`;
        };

        return `
        <div class="group relative ${cardBgClass} ${complaintClass} rounded-xl p-5 flex flex-col items-center text-center shadow-lg border hover:shadow-2xl hover:-translate-y-1 transition-all duration-300 overflow-hidden">
            ${recurringBadge}
            
            <div class="mt-4 mb-3 relative">
                <div class="w-16 h-16 rounded-full flex items-center justify-center text-2xl font-black uppercase shadow-sm ring-4 ${ringClass}">
                    <span>${initial}</span>
                </div>
            </div>
            <div class="w-full mb-3">
                <h4 class="font-black text-2xl uppercase ${textMainClass} leading-tight mb-1 truncate px-2" title="${fullName}">
                    ${fullName}
                </h4>
                <p class="text-xs ${textSubClass} font-medium truncate px-4 flex justify-center items-center gap-1">
                    <i data-lucide="mail" class="w-3 h-3"></i> ${client.email || '<span class="italic opacity-70">Sin correo</span>'}
                </p>
            </div>
            <div class="w-full mb-2 min-h-[28px] flex flex-wrap justify-center content-center px-2">
                ${servicesHtml}
            </div>
            <div class="w-full border-t border-white/10 pt-1">
                ${renderDarkActivitySummary(client)} 
            </div>
            <div class="flex gap-3 mt-5 w-full">
                <button class="flex-1 ${buttonClass} font-black py-2.5 px-3 rounded-lg text-lg uppercase shadow hover:shadow-lg transition-all flex items-center justify-center gap-2 edit-client-btn" data-client-id="${client.id}">
                    <i data-lucide="user" class="w-4 h-4"></i> VER PERFIL
                </button>
                <button class="p-2.5 bg-red-600 hover:bg-red-700 text-white rounded-lg transition-all border-none group/del delete-btn" data-item-id="${client.id}" title="Eliminar Cliente">
                    <i data-lucide="trash-2" class="w-4 h-4 transition-transform group-hover"></i>
                </button>
            </div>
        </div>`;
    };

    const renderClientTableRow = (client) => {
        const fullName = `${client.nombre || ''} ${client.apellido || ''}`.trim();
        const recurringTag = client.is_recurring ? `<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-black [var(--color-secondary)] text-white ml-2"><i data-lucide="repeat" class="w-3 h-3 mr-1"></i> RECURRENTE</span>` : '';
        const contactInfo = `${client.email || ''}<br><span class="text-gray-400 text-xs">${formatPhoneNumber(client.mobile) || formatPhoneNumber(client.phone) || ''}</span>`.trim();
        const servicesHtml = client.servicios ? client.servicios.split(', ').map(s => `<span class="inline-block ${getServiceTagColors(s).bg} ${getServiceTagColors(s).text} py-0.5 px-2 rounded-full text-xs font-semibold mr-1 mb-1">${s}</span>`).join('') : '<p class="text-gray-300 text-xs italic">SIN SERVICIOS</p>';
        
        const rowBorderClass = client.is_recurring ? 'border-l-4 border-l-[var(--color-secondary)]' : 'border-l-4 border-l-[var(--color-primary)]';


        return `<tr class="flex flex-col md:table-row bg-white mb-4 md:mb-0 shadow-sm md:shadow-none rounded-xl md:rounded-none border border-gray-200 md:border-b md:border-x-0 md:border-t-0 hover:bg-gray-50 p-4 md:p-0 transition-colors ${rowBorderClass}">
            <td class="flex justify-between items-center md:table-cell w-full md:w-auto py-3 md:py-4 px-0 md:px-6 border-b md:border-none last:border-0" data-label="Nombre">
                <span class="block md:hidden font-bold text-xs text-gray-500 uppercase">NOMBRE</span>
                <div class="text-right md:text-left"><span class="font-bold text-[var(--color-primary)] cursor-pointer edit-client-btn hover:text-[var(--color-secondary)] transition-colors" data-client-id="${client.id}">${fullName}</span>${recurringTag}</div>
            </td>
            <td class="flex justify-between items-center md:table-cell w-full md:w-auto py-2 md:py-4 px-0 md:px-6 border-b md:border-none last:border-0" data-label="Contacto">
                <span class="block md:hidden font-bold text-xs text-gray-500 uppercase">CONTACTO</span>
                <div class="text-right md:text-left text-sm text-gray-700">${contactInfo}</div>
            </td>
            <td class="flex justify-between items-center md:table-cell w-full md:w-auto py-2 md:py-4 px-0 md:px-6 border-b md:border-none last:border-0" data-label="Servicios">
                <span class="block md:hidden font-bold text-xs text-gray-500 uppercase">SERVICIOS</span>
                <div class="text-right md:text-left">${servicesHtml}</div>
            </td>
            <td class="flex justify-between items-center md:table-cell w-full md:w-auto py-2 md:py-4 px-0 md:px-6 border-b md:border-none last:border-0" data-label="Actividad Pendiente">
                <span class="block md:hidden font-bold text-xs text-gray-500 uppercase">ACTIVIDAD</span>
                <div class="text-right md:text-left">${renderActivitySummary(client, true)}</div>
            </td>
            <td class="flex justify-between items-center md:table-cell w-full md:w-auto py-2 md:py-4 px-0 md:px-6 border-b md:border-none last:border-0" data-label="Acciones">
                <span class="block md:hidden font-bold text-xs text-gray-500 uppercase">ACCIONES</span>
                <div class="flex justify-end items-center gap-2">
                    <button class="text-[var(--color-primary)] hover:text-[var(--color-secondary)] edit-client-btn" data-client-id="${client.id}" title="Ver Detalles"><i data-lucide="eye" class="w-5 h-5"></i></button>
                    <button class="text-[var(--color-secondary)] hover:text-[var(--color-primary)] delete-btn" data-item-id="${client.id}" title="Eliminar Cliente"><i data-lucide="trash-2" class="w-5 h-5"></i></button>
                </div>
            </td>
        </tr>`;
    };

    window.openClientDetailsModal = async (clientId) => {
        currentReadOnlyClientId = clientId;
        openPanel('viewClienteReadOnlyPanel');
        document.getElementById('readonly-cliente-full-name').textContent = 'Cargando...';
        document.getElementById('readonly-invoices-list').innerHTML = '<div class="flex justify-center p-4"><i data-lucide="loader-2" class="animate-spin w-6 h-6"></i></div>';
        document.getElementById('readonly-appointments-list').innerHTML = '';
        
        try {
            // CORRECCIÓN CRÍTICA: Se ajusta el nombre del archivo a 'get-client-details.php' (guion medio)
            const response = await fetch(`db/get-client-details.php?id=${clientId}`);
            const result = await response.json();
            if (!result.success) throw new Error(result.message);

            const c = result.client;
            const d = result.data;

            document.getElementById('readonly-cliente-full-name').textContent = `${c.first_name} ${c.last_name || ''}`;
            document.getElementById('readonly-cliente-email').textContent = c.email || '---';
            document.getElementById('readonly-cliente-phone').textContent = formatPhoneNumber(c.phone) || '---';
            document.getElementById('readonly-cliente-mobile').textContent = formatPhoneNumber(c.mobile) || '---';
            document.getElementById('readonly-access-code').value = c.access_code || '';
            document.getElementById('readonly-cliente-full-address').textContent = c.street_address || 'Sin dirección';

            const servicesContainer = document.getElementById('readonly-cliente-services-display');
            if (c.services_list) {
                servicesContainer.innerHTML = c.services_list.split(', ').map(s => 
                    `<span class="inline-flex items-center px-2 py-1 rounded-md text-xs font-medium bg-blue-50 text-blue-700 border border-blue-100 mr-1 mb-1">${s}</span>`
                ).join('');
            } else {
                servicesContainer.innerHTML = '<span class="text-gray-400 text-xs italic">Sin servicios asignados</span>';
            }

            const invContainer = document.getElementById('readonly-invoices-list');
            if (d.invoices.length > 0) {
                invContainer.innerHTML = d.invoices.map(inv => {
                    const color = inv.status === 'pagada' ? 'text-green-600 bg-green-50' : 'text-red-600 bg-red-50';
                    return `
                    <div class="flex justify-between items-center p-2 border rounded hover:bg-gray-50">
                        <div>
                            <div class="font-bold text-xs text-gray-700">#${inv.external_id}</div>
                            <div class="text-md text-gray-400">${inv.invoice_date}</div>
                        </div>
                        <div class="text-right">
                            <div class="font-bold text-sm">$${parseFloat(inv.total_amount).toFixed(2)}</div>
                            <span class="text-md uppercase px-1 rounded ${color}">${inv.status}</span>
                        </div>
                    </div>`;
                }).join('');
            } else {
                invContainer.innerHTML = '<p class="text-gray-400 text-sm text-center py-4">No hay facturas recientes.</p>';
            }

            const apptContainer = document.getElementById('readonly-appointments-list');
            if (d.appointments.length > 0) {
                apptContainer.innerHTML = d.appointments.map(app => `
                    <div class="flex justify-between items-center p-2 border rounded hover:bg-gray-50 border-l-4 border-l-blue-500">
                        <div>
                            <div class="font-bold text-xs text-gray-800">${app.appointment_date}</div>
                            <div class="text-md text-gray-500">${app.appointment_time}</div>
                        </div>
                        <span class="text-md uppercase px-2 py-0.5 rounded bg-gray-100 text-gray-600">${app.status}</span>
                    </div>`).join('');
            } else {
                apptContainer.innerHTML = '<p class="text-gray-400 text-sm text-center py-4">No hay citas programadas.</p>';
            }

            const taskContainer = document.getElementById('readonly-tasks-list');
            if (d.tasks.length > 0) {
                taskContainer.innerHTML = d.tasks.map(t => {
                    const priorityColor = t.priority === 'Alta' ? 'text-red-600' : (t.priority === 'Media' ? 'text-yellow-600' : 'text-green-600');
                    return `
                    <div class="flex items-start p-2 border rounded hover:bg-gray-50">
                        <i data-lucide="check-square" class="w-4 h-4 mt-1 mr-2 text-gray-400"></i>
                        <div class="flex-1">
                            <div class="font-semibold text-md text-gray-700">${t.title}</div>
                            <div class="flex justify-between mt-1">
                                <span class="text-md text-gray-400">Vence: ${t.due_date}</span>
                                <span class="text-md font-bold ${priorityColor}">${t.priority}</span>
                            </div>
                        </div>
                    </div>`;
                }).join('');
            } else {
                taskContainer.innerHTML = '<p class="text-gray-400 text-sm text-center py-4">No hay tareas pendientes.</p>';
            }
            
            const estContainer = document.getElementById('readonly-estimates-list');
            if (d.estimates.length > 0) {
                estContainer.innerHTML = d.estimates.map(est => `
                    <div class="flex justify-between items-center p-2 border rounded hover:bg-gray-50">
                        <div>
                            <div class="font-bold text-xs text-gray-700">#${est.external_id}</div>
                            <div class="text-md text-gray-400">${est.estimate_date}</div>
                        </div>
                        <div class="text-right">
                            <div class="font-bold text-sm">$${parseFloat(est.total_amount).toFixed(2)}</div>
                            <span class="text-md uppercase px-1 rounded bg-orange-50 text-orange-600">${est.status}</span>
                        </div>
                    </div>`).join('');
            } else {
                estContainer.innerHTML = '<p class="text-gray-400 text-sm text-center py-4">No hay cotizaciones recientes.</p>';
            }

            if(typeof lucide !== 'undefined') lucide.createIcons();
            switchTab('tab-invoices');

        } catch (error) {
            console.error("Error:", error);
            showToast("Error al cargar detalles: " + error.message, 'error');
        }
    };

    window.openEditClienteModal = (clientId) => {
        const client = clientsFromDB[clientId];
        if (!client) return;
        document.getElementById('view-cliente-id').value = client.id;
        document.getElementById('view-cliente-first-name').value = client.nombre || '';
        document.getElementById('view-cliente-last-name').value = client.apellido || '';
        document.getElementById('view-cliente-email').value = client.email || '';
        document.getElementById('view-cliente-phone').value = client.phone || '';
        document.getElementById('view-cliente-mobile').value = client.mobile || '';
        document.getElementById('view-cliente-direccion-calle').value = client.direccion_calle || '';
        document.getElementById('view-cliente-ciudad').value = client.ciudad || '';
        document.getElementById('view-cliente-estado-field').value = client.state_province || '';
        document.getElementById('view-cliente-codigo-postal').value = client.zip_code || '';
        document.getElementById('view-cliente-is-recurring').checked = client.is_recurring;
        viewSelectedServiceIds.clear();
        (client.service_ids || []).forEach(id => viewSelectedServiceIds.add(id));
        renderSelectedServices(viewSelectedServiceIds, document.getElementById('view-selected-services-container'), document.getElementById('view-cliente-servicios'));
        closePanel('viewClienteReadOnlyPanel');
        openPanel('viewClientePanel');
    };

    const renderClients = () => {
        const DOMElements = { clientSearch: document.getElementById('client-search'), clientFilterType: document.getElementById('client-filter-type'), clientFilterApellidoLetter: document.getElementById('client-filter-apellido-letter'), clientFilterService: document.getElementById('client-filter-service'), clientGridView: document.getElementById('client-grid-view'), clientListView: document.getElementById('client-list-view'), clientsTableBody: document.getElementById('clientsTableBody'), gridViewBtn: document.getElementById('grid-view-btn'), listViewBtn: document.getElementById('list-view-btn') };
        const searchTerm = DOMElements.clientSearch.value.toLowerCase();
        
        const selectedType = DOMElements.clientFilterType.value;
        const selectedLetter = DOMElements.clientFilterApellidoLetter.value;
        const selectedServiceId = parseInt(DOMElements.clientFilterService.value);
        
        const filteredClients = Object.values(clientsFromDB).filter(c => {
            const fullName = `${c.nombre || ''} ${c.apellido || ''}`.trim().toLowerCase();
            const initial = (c.apellido || c.nombre || ' ').charAt(0).toUpperCase();
            
            const matchesSearch = fullName.includes(searchTerm) || (c.servicios || '').toLowerCase().includes(searchTerm);
            const matchesLetter = selectedLetter === 'all' || initial === selectedLetter;
            const matchesService = isNaN(selectedServiceId) || selectedServiceId === 0 || (c.service_ids || []).includes(selectedServiceId);
            
            // NUEVA LÓGICA DE FILTRADO POR TIPO
            let matchesType = true;
            if (selectedType === 'recurring') {
                matchesType = c.is_recurring;
            } else if (selectedType === 'standard') {
                matchesType = !c.is_recurring;
            }
            
            return matchesSearch && matchesLetter && matchesService && matchesType;
        });

        // Optimizamos el renderizado de los loops:
        let gridHtml = '';
        let listHtml = '';

        if (filteredClients.length > 0) {
             filteredClients.forEach(client => {
                gridHtml += renderClientCard(client);
                listHtml += renderClientTableRow(client);
            });
        } else {
             gridHtml = `<p class="text-center py-8 text-gray-500 md:col-span-3">No se encontraron clientes</p>`;
             listHtml = `<tr><td colspan="5" class="text-center py-8 text-gray-500">No se encontraron clientes</td></tr>`;
        }
        
        DOMElements.clientGridView.innerHTML = gridHtml;
        DOMElements.clientsTableBody.innerHTML = listHtml;
        
        DOMElements.clientGridView.classList.toggle('hidden', currentClientView !== 'grid');
        DOMElements.clientListView.classList.toggle('hidden', currentClientView !== 'list');
        
        if(currentClientView === 'grid') {
            DOMElements.gridViewBtn.classList.add('bg-white', 'text-gray-800', 'shadow-sm');
            DOMElements.gridViewBtn.classList.remove('bg-transparent', 'text-gray-500');
            DOMElements.listViewBtn.classList.add('bg-transparent', 'text-gray-500');
            DOMElements.listViewBtn.classList.remove('bg-white', 'text-gray-800', 'shadow-sm');
        } else {
            DOMElements.listViewBtn.classList.add('bg-white', 'text-gray-800', 'shadow-sm');
            DOMElements.listViewBtn.classList.remove('bg-transparent', 'text-gray-500');
            DOMElements.gridViewBtn.classList.add('bg-transparent', 'text-gray-500');
            DOMElements.gridViewBtn.classList.remove('bg-white', 'text-gray-800', 'shadow-sm');
        }
        
        if(typeof lucide !== 'undefined') lucide.createIcons();
    };

    const populateFilters = () => {
        const initials = [...new Set(Object.values(clientsFromDB).map(c => (c.apellido || c.nombre || ' ').charAt(0).toUpperCase()))].sort();
        document.getElementById('client-filter-apellido-letter').innerHTML = `<option value="all">Todas Las Letras</option>${initials.map(i => `<option value="${i}">${i}</option>`).join('')}`;
        document.getElementById('client-filter-service').innerHTML = `<option value="0">Todos Los Servicios</option>${availableServices.map(s => `<option value="${s.id}">${s.name}</option>`).join('')}`;
        const monthNames = ["", "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"];
        const uniqueMonths = [...new Set(monthsWithClients.map(m => `${m.year}-${m.month}`))].sort((a, b) => b.localeCompare(a));
        document.getElementById('monthly-filter-select').innerHTML = uniqueMonths.map(val => {
            const [y, m] = val.split('-');
            return `<option value="${y}-${m}" ${y == selectedYear && m == selectedMonth ? 'selected' : ''}>${monthNames[parseInt(m)]} ${y}</option>`;
        }).join('');
    };
    
    const renderSelectedServices = (selectedIdsSet, container, hiddenInput) => {
        const servicesArray = Array.from(selectedIdsSet);
        hiddenInput.value = servicesArray.join(',');
        if (servicesArray.length === 0) {
            container.innerHTML = '<p class="text-gray-500 text-sm italic">NINGÚN SERVICIO SELECCIONADO</p>';
        } else {
            container.innerHTML = servicesArray.map(id => {
                const service = availableServices.find(s => s.id == id);
                return service ? `<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-[var(--color-primary)] text-white gap-1"><span>${service.name.toUpperCase()}</span><button type="button" class="remove-service-btn" data-service-id="${id}"><i data-lucide="x" class="w-4 h-4"></i></button></span>` : '';
            }).join('');
        }
        if(typeof lucide !== 'undefined') lucide.createIcons();
    };

    const setupServiceSearch = (input, resultsDiv, selectedIds, container, hiddenInput) => {
        input.addEventListener('input', e => {
            const query = e.target.value.toLowerCase();
            if (query.length < 1) { resultsDiv.classList.add('hidden'); return; }
            const filtered = availableServices.filter(s => s.name.toLowerCase().includes(query) && !selectedIds.has(s.id));
            resultsDiv.innerHTML = filtered.length > 0 ? filtered.map(s => `<div class="p-2 cursor-pointer hover:bg-gray-100" data-service-id="${s.id}">${s.name}</div>`).join('') : '<div class="p-2 text-gray-500">No hay resultados</div>';
            resultsDiv.classList.remove('hidden');
        });
        resultsDiv.addEventListener('mousedown', e => {
            if (e.target.dataset.serviceId) {
                const id = parseInt(e.target.dataset.serviceId);
                selectedIds.add(id);
                renderSelectedServices(selectedIds, container, hiddenInput);
                input.value = '';
                resultsDiv.classList.add('hidden');
            }
        });
        container.addEventListener('click', e => {
            const btn = e.target.closest('.remove-service-btn');
            if(btn) {
                selectedIds.delete(parseInt(btn.dataset.serviceId));
                renderSelectedServices(selectedIds, container, hiddenInput);
            }
        });
        document.addEventListener('click', e => { if (!input.contains(e.target) && !resultsDiv.contains(e.target)) resultsDiv.classList.add('hidden'); });
    };

    const setupProspectSearch = () => { 
        const input = document.getElementById('cliente-prospecto-search');
        const resultsDiv = document.getElementById('prospect-search-results');
        input.addEventListener('input', e => {
            const query = e.target.value.toLowerCase();
            if (query.length < 2) { resultsDiv.classList.add('hidden'); return; }
            const filtered = Object.values(prospectsFromDB).filter(p => `${p.first_name} ${p.last_name}`.toLowerCase().includes(query) || p.email.toLowerCase().includes(query));
            resultsDiv.innerHTML = filtered.length > 0 ? filtered.map(p => `<div class="p-2 cursor-pointer hover:bg-gray-100" data-prospect-id="${p.id}">${p.first_name} ${p.last_name} (${p.email})</div>`).join('') : '<div class="p-2 text-gray-500">No hay resultados</div>';
            resultsDiv.classList.remove('hidden');
        });
        resultsDiv.addEventListener('mousedown', e => {
            if(e.target.dataset.prospectId) {
                const prospect = prospectsFromDB[e.target.dataset.prospectId];
                if (prospect) {
                    document.getElementById('cliente-first-name').value = prospect.first_name;
                    document.getElementById('cliente-last-name').value = prospect.last_name;
                    document.getElementById('cliente-email').value = prospect.email;
                    document.getElementById('cliente-phone').value = prospect.phone;
                    document.getElementById('cliente-mobile').value = prospect.mobile;
                    document.getElementById('cliente-direccion-calle').value = prospect.street_address;
                    document.getElementById('cliente-ciudad').value = prospect.city;
                    document.getElementById('cliente-estado-field').value = prospect.state_province;
                    document.getElementById('cliente-codigo-postal').value = prospect.zip_code;
                    document.getElementById('cliente-selected-prospect-id').value = prospect.id;
                    input.value = `${prospect.first_name} ${prospect.last_name}`;
                    resultsDiv.classList.add('hidden');
                }
            }
        });
        document.addEventListener('click', e => { if (!input.contains(e.target) && !resultsDiv.contains(e.target)) resultsDiv.classList.add('hidden'); });
    };

    document.addEventListener('DOMContentLoaded', () => {
        populateFilters();
        renderClients();
        
        document.getElementById('client-search').addEventListener('input', renderClients);
        // Evento para el nuevo filtro
        document.getElementById('client-filter-type').addEventListener('change', renderClients);
        document.getElementById('client-filter-apellido-letter').addEventListener('change', renderClients);
        document.getElementById('client-filter-service').addEventListener('change', renderClients);
        document.getElementById('monthly-filter-select').addEventListener('change', e => {
            const [year, month] = e.target.value.split('-');
            window.location.href = `clients.php?year=${year}&month=${month}`;
        });
        document.getElementById('grid-view-btn').addEventListener('click', () => { currentClientView = 'grid'; renderClients(); });
        document.getElementById('list-view-btn').addEventListener('click', () => { currentClientView = 'list'; renderClients(); });
        
        const contentArea = document.getElementById('content-area');
        contentArea.addEventListener('click', e => {
            const editBtn = e.target.closest('.edit-client-btn');
            if (editBtn) openClientDetailsModal(editBtn.dataset.clientId);
            
            const deleteBtn = e.target.closest('.delete-btn');
            if (deleteBtn) {
                const clientId = deleteBtn.dataset.itemId;
                
                // Función de acción para el botón de confirmación
                const confirmAction = async (btn) => {
                    const originalHtml = '<i data-lucide="trash-2" class="w-5 h-5"></i> ELIMINAR';
                    
                    try {
                        const response = await fetch('db/clients-delete.php', {
                            method: 'POST',
                            headers: {'Content-Type': 'application/json'},
                            body: JSON.stringify({ id: clientId })
                        });
                        const result = await response.json();
                        
                        if (result.success) {   
                            showToast('CLIENTE ELIMINADO', 'success');
                            closeModal('confirmDeleteModal'); // Cierra modal al éxito
                            setTimeout(() => location.reload(), 500);  
                        } else {    
                            // Manejo de error específico
                            showToast('Error al eliminar: ' + result.message, 'error');
                            // Revertir botón
                            btn.innerHTML = originalHtml;
                            btn.disabled = false;
                            if(typeof lucide !== 'undefined') lucide.createIcons();
                        }
                    } catch (error) {
                        showToast('Error de conexión', 'error');
                        // Revertir botón
                        btn.innerHTML = originalHtml;
                        btn.disabled = false;
                        if(typeof lucide !== 'undefined') lucide.createIcons();
                    }
                };
                
                const clientToDelete = clientsFromDB[clientId];
                const clientFullName = `${clientToDelete.nombre || ''} ${clientToDelete.apellido || ''}`.trim().toUpperCase();
                
                openConfirmationModal(
                    '¿CONFIRMAS LA ELIMINACIÓN DEL CLIENTE', 
                    clientFullName + '?', 
                    confirmAction
                );
                // Asegurar que el botón de eliminar tenga el texto correcto antes de que el usuario haga clic
                document.getElementById('confirm-delete-button').innerHTML = '<i data-lucide="trash-2" class="w-5 h-5"></i> ELIMINAR';
                if(typeof lucide !== 'undefined') lucide.createIcons();
            }
        });

        document.getElementById('edit-client-from-readonly-btn').addEventListener('click', () => {
            if (currentReadOnlyClientId) openEditClienteModal(currentReadOnlyClientId);
        });

        const accessCodeInput = document.getElementById('readonly-access-code');
        const toggleBtn = document.getElementById('toggle-access-code-btn');
        const copyBtn = document.getElementById('copy-access-code-btn');
        const generateBtn = document.getElementById('generate-access-code-btn');
        const deleteCodeBtn = document.getElementById('delete-access-code-btn');

        toggleBtn.addEventListener('click', () => {
            const icon = toggleBtn.querySelector('i');
            if (accessCodeInput.type === 'password') {
                accessCodeInput.type = 'text';
                icon.setAttribute('data-lucide', 'eye-off');
            } else {
                accessCodeInput.type = 'password';
                icon.setAttribute('data-lucide', 'eye');
            }
            if(typeof lucide !== 'undefined') lucide.createIcons();
        });
        
        copyBtn.addEventListener('click', (e) => {
            const isPassword = accessCodeInput.type === 'password';
            if (isPassword) accessCodeInput.type = 'text';
            accessCodeInput.select();
            document.execCommand('copy');
            if (isPassword) accessCodeInput.type = 'password';
            const icon = e.currentTarget.querySelector('i');
            icon.setAttribute('data-lucide', 'check');
            if(typeof lucide !== 'undefined') lucide.createIcons();
            setTimeout(() => {
                icon.setAttribute('data-lucide', 'copy');
                if(typeof lucide !== 'undefined') lucide.createIcons();
            }, 1500);
        });
        
        generateBtn.addEventListener('click', () => {
            if (!currentReadOnlyClientId) return;
            const confirmAction = async (btn) => {
                const originalHtml = '<i data-lucide="refresh-cw" class="w-5 h-5"></i> GENERAR';
                
                try {
                    const response = await fetch('db/clients-generate-code.php', {
                        method: 'POST',
                        headers: {'Content-Type': 'application/json'},
                        body: JSON.stringify({ client_id: currentReadOnlyClientId })
                    });
                    const result = await response.json();
                    if (result.success) {
                        accessCodeInput.value = result.new_code;
                        clientsFromDB[currentReadOnlyClientId].access_code = result.new_code;
                        showToast('CÓDIGO GENERADO', 'success');
                        closeModal('confirmGenerateCodeModal');
                    } else {
                        showToast('Error al generar el código: ' + result.message, 'error');
                        closeModal('confirmGenerateCodeModal');
                        btn.innerHTML = originalHtml;
                        btn.disabled = false;
                        if(typeof lucide !== 'undefined') lucide.createIcons();
                    }
                } catch(e) {
                    showToast('Error de conexión', 'error');
                    closeModal('confirmGenerateCodeModal');
                    btn.innerHTML = originalHtml;
                    btn.disabled = false;
                    if(typeof lucide !== 'undefined') lucide.createIcons();
                }
            };

            const clientNameForCode = clientsFromDB[currentReadOnlyClientId].nombre + ' ' + clientsFromDB[currentReadOnlyClientId].apellido;
            const clientFullName = clientNameForCode.trim().toUpperCase();
            
            openGenerateCodeModal(
                document.getElementById('generate-code-modal-message').textContent, 
                clientFullName + '?',              
                confirmAction
            );
        });

        deleteCodeBtn.addEventListener('click', () => {
            if (!currentReadOnlyClientId) return;
            const confirmAction = async (btn) => {
                const originalHtml = '<i data-lucide="trash-2" class="w-5 h-5"></i> ELIMINAR';
                
                try {
                    const response = await fetch('db/clients-delete-code.php', {
                        method: 'POST',
                        headers: {'Content-Type': 'application/json'},
                        body: JSON.stringify({ client_id: currentReadOnlyClientId })
                    });
                    const result = await response.json();
                    if (result.success) {
                        accessCodeInput.value = 'N/A';
                        clientsFromDB[currentReadOnlyClientId].access_code = null;
                        showToast('CÓDIGO ELIMINADO', 'success');
                        closeModal('confirmDeleteModal');
                    } else {
                        showToast('Error al eliminar el código: ' + result.message, 'error');
                        closeModal('confirmDeleteModal');
                        btn.innerHTML = originalHtml;
                        btn.disabled = false;
                        if(typeof lucide !== 'undefined') lucide.createIcons();
                    }
                } catch (e) {
                    showToast('Error de conexión', 'error');
                    closeModal('confirmDeleteModal');
                    btn.innerHTML = originalHtml;
                    btn.disabled = false;
                    if(typeof lucide !== 'undefined') lucide.createIcons();
                }
            };

            const clientNameForDeleteCode = clientsFromDB[currentReadOnlyClientId].nombre + ' ' + clientsFromDB[currentReadOnlyClientId].apellido;
            const clientFullName = clientNameForDeleteCode.trim().toUpperCase();
            
            openConfirmationModal(
                '¿ESTÁS SEGURO DE ELIMINAR EL CÓDIGO DE ACCESO DE',
                clientFullName + '?',
                confirmAction
            );
            document.getElementById('confirm-delete-button').innerHTML = '<i data-lucide="trash-2" class="w-5 h-5"></i> ELIMINAR';
        });
        
        setupProspectSearch();
        setupServiceSearch(document.getElementById('cliente-servicio-search'), document.getElementById('service-search-results'), selectedServiceIds, document.getElementById('selected-services-container'), document.getElementById('cliente-servicios'));
        setupServiceSearch(document.getElementById('view-cliente-servicio-search'), document.getElementById('view-service-search-results'), viewSelectedServiceIds, document.getElementById('view-selected-services-container'), document.getElementById('view-cliente-servicios'));
        
        document.getElementById('add-cliente-form').addEventListener('submit', async (e) => {
            e.preventDefault();
            const formData = {
                first_name: document.getElementById('cliente-first-name').value,
                last_name: document.getElementById('cliente-last-name').value,
                email: document.getElementById('cliente-email').value,
                phone: document.getElementById('cliente-phone').value,
                mobile: document.getElementById('cliente-mobile').value,
                street_address: document.getElementById('cliente-direccion-calle').value,
                city: document.getElementById('cliente-ciudad').value,
                state_province: document.getElementById('cliente-estado-field').value,
                zip_code: document.getElementById('cliente-codigo-postal').value,
                assigned_service_ids: Array.from(selectedServiceIds),
                prospect_id: document.getElementById('cliente-selected-prospect-id').value,
                is_recurring: document.getElementById('cliente-is-recurring').checked
            };
            const response = await fetch('db/clients-create.php', {
                method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(formData)
            });
            const result = await response.json();
            if (result.success) {   
                showToast('CLIENTE AGREGADO', 'success');
                setTimeout(() => location.reload(), 1000);
            } else {    
                showToast('Error: ' + result.message, 'error'); 
            }
        });
        
        document.getElementById('view-cliente-form').addEventListener('submit', async (e) => {
            e.preventDefault();
            const formData = {
                id: document.getElementById('view-cliente-id').value,
                first_name: document.getElementById('view-cliente-first-name').value,
                last_name: document.getElementById('view-cliente-last-name').value,
                email: document.getElementById('view-cliente-email').value,
                phone: document.getElementById('view-cliente-phone').value,
                mobile: document.getElementById('view-cliente-mobile').value,
                street_address: document.getElementById('view-cliente-direccion-calle').value,
                city: document.getElementById('view-cliente-ciudad').value,
                state_province: document.getElementById('view-cliente-estado-field').value,
                zip_code: document.getElementById('view-cliente-codigo-postal').value,
                assigned_service_ids: Array.from(viewSelectedServiceIds),
                is_recurring: document.getElementById('view-cliente-is-recurring').checked
            };
            const response = await fetch('db/clients-update.php', { 
                method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(formData)
            });
            const result = await response.json();
            if (result.success) {   
                showToast('CLIENTE ACTUALIZADO', 'success');
                setTimeout(() => location.reload(), 1000);
            } else {    
                showToast('Error: ' + result.message, 'error'); 
            }
        });
        
        if(typeof lucide !== 'undefined') lucide.createIcons();
    });
</script>
<script src="files/toast.js"></script>
</body>
</html>