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

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

include_once 'db/db_connection.php';

$all_transactions = [];
try {
    $stmt = $pdo->query("
        SELECT 
            f.id, 
            f.type, 
            f.description, 
            f.amount, 
            f.transaction_date, 
            f.client_id,
            CONCAT(c.first_name, ' ', c.last_name) as client_name
        FROM finances f
        LEFT JOIN clients c ON f.client_id = c.id
        ORDER BY f.transaction_date DESC, f.id DESC
    ");
    $all_transactions = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    error_log("Error al cargar finanzas desde la DB en finances.php: " . $e->getMessage());
}

$all_recurring_expenses = [];
try {
    $stmt = $pdo->query("
        SELECT 
            rf.id, 
            rf.type, 
            rf.description, 
            rf.amount, 
            rf.recurrence_day_of_month,
            rf.start_date,
            rf.end_date,
            rf.client_id,
            CONCAT(c.first_name, ' ', c.last_name) as client_name
        FROM recurring_finances rf
        LEFT JOIN clients c ON rf.client_id = c.id
        WHERE rf.type = 'gasto'
        ORDER BY rf.recurrence_day_of_month ASC, rf.description ASC
    ");
    $all_recurring_expenses = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    error_log("Error al cargar egresos recurrentes en finances.php: " . $e->getMessage());
}

$transactions_json = json_encode($all_transactions);
$recurring_expenses_json = json_encode($all_recurring_expenses);

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>Panel Financiero FlowCRM™  De OrozDesign Powered By OrozCO</title>
  <meta name="robots" content="noindex, nofollow">

    <link rel="icon" type="image/png" href="img/favicon.png">
    <link rel="apple-touch-icon" href="img/apple-touch-icon.png">
    
    <?php include 'files/gtm-head.php'; ?>
    
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Barlow:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
    
    <script src="https://unpkg.com/lucide@latest"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://unpkg.com/imask"></script>

    <link rel="stylesheet" href="style.css">
    <script src="files/header-manager.js"></script>
    
    <style>
        .autocomplete-suggestions{border:1px solid #ddd;background:#fff;max-height:150px;overflow-y:auto;position:absolute;z-index:100;width:100%;box-shadow:0 2px 5px rgba(0,0,0,0.1)}.autocomplete-suggestion-item{padding:8px 10px;cursor:pointer;border-bottom:1px solid #eee}.autocomplete-suggestion-item:last-child{border-bottom:none}.autocomplete-suggestion-item:hover{background-color:#f0f0f0}.styled-readonly-input{background-color:#e9e9ed;cursor:not-allowed;border:1px solid #d1d5db;color:#4b5563;font-weight:600;box-shadow:inset 0 1px 2px rgba(0,0,0,0.06)}.recurring-tag{background-color:#a78bfa;color:#4c1d95;padding:.25rem .5rem;border-radius:9999px;font-size:.75rem;font-weight:700;margin-left:.5rem;display:inline-flex;align-items:center}
        
        /* === NUEVAS REGLAS PARA TABLAS RESPONSIVAS EN FINANZAS === */
        @media (max-width: 767px) {
            /* Reglas base para todas las tablas que se quieren apilar */
            .responsive-table-stack tbody,
            .responsive-table-stack tr,
            .responsive-table-stack td {
                display: block;
                width: 100%;
            }

            .responsive-table-stack thead {
                display: none; /* Oculta el encabezado de la tabla original */
            }

            .responsive-table-stack tr {
                margin-bottom: 1rem; /* Espacio entre las "tarjetas" de fila */
                border: 1px solid #e2e8f0;
                border-radius: 0.5rem;
                padding: 0.5rem;
                background-color: white;
                box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
            }

            .responsive-table-stack td {
                text-align: right !important; /* Alinea el valor a la derecha */
                padding-left: 50% !important; /* Deja espacio para la etiqueta */
                position: relative;
                border-bottom: 1px solid #edf2f7; /* Separador entre campos */
                padding-top: 0.75rem;
                padding-bottom: 0.75rem;
                white-space: normal; /* Permite que el texto se ajuste */
                word-break: break-word; /* Rompe palabras largas */
            }

            .responsive-table-stack td:last-child {
                border-bottom: 0; /* No hay borde inferior en el último campo */
            }

            /* Etiqueta del campo (header) */
            .responsive-table-stack td::before {
                content: attr(data-label); /* Usa el atributo data-label como contenido */
                position: absolute;
                left: 0.75rem;
                width: calc(50% - 1.5rem); /* Ocupa la mitad izquierda */
                padding-right: 1rem;
                white-space: nowrap; /* Evita que la etiqueta se rompa */
                text-align: left;
                font-weight: bold;
                text-transform: uppercase;
                color: #4a5568;
                flex-shrink: 0;
            }

            /* Ajustes para celdas de acciones/botones */
            .responsive-table-stack td.actions-cell {
                text-align: center !important;
                padding-left: 0 !important;
                display: flex;
                justify-content: center;
                align-items: center;
                gap: 0.75rem; /* Espacio entre botones */
                min-height: 48px; /* Altura mínima para la fila de botones */
                flex-wrap: wrap; /* Permite que los botones se envuelvan si hay muchos */
            }

            .responsive-table-stack td.actions-cell::before {
                content: none; /* No mostrar etiqueta para celdas de acciones */
            }

            /* Asegurar que los botones dentro de celdas de acción se apilen si es necesario */
            .responsive-table-stack td.actions-cell button {
                width: auto; /* O auto para que no tomen todo el ancho */
                flex-grow: 1; /* Permite que crezcan para llenar el espacio, o 0 para que no */
                min-width: 80px; /* Asegura un tamaño mínimo para el botón */
            }

            /* Para la tabla de resumen histórico y gastos recurrentes */
            #finance-summary-table-body td,
            #recurring-expenses-table-body td {
                /* Ya se manejan por .responsive-table-stack */
            }
        }
    </style>
</head>
<body data-page-title="Centro De Control Financiero" 
      data-page-subtitle="Administra Las Entradas Y Salidas Económicas De Tu Negocio" 
      data-page-icon="chart-no-axes-combined">

    <div id="toast-container" class="toast-container"></div>
        
<?php include 'files/gtm-body.php'; ?>

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

    <div id="sidebar-overlay" class="fixed inset-0 bg-black bg-opacity-50 z-30 hidden md:hidden"></div>
    <div id="task-panel-overlay" class="off-canvas-overlay"></div> 
    
    <?php include 'menu.php'; ?>

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

        <div id="content-area" class="p-4 md:p-8 space-y-8">
            <section id="finanzas" class="dashboard-section">
                <div class="bg-white p-6 rounded-xl shadow-md">
                    <div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-6 gap-4">
                        <div>
                            <h3 class="text-2xl font-extrabold text-gray-800 flex items-center gap-2">
                                <i data-lucide="trending-up" class="w-7 h-7 text-[var(--color-primary)]"></i> ANÁLISIS FINANCIERO
                            </h3>
                            <p class="text-gray-500 text-sm mt-1 uppercase">REVISA TUS INGRESOS, GASTOS Y EL FLUJO DE EFECTIVO.</p>
                        </div>
                        <div class="flex items-center gap-4 w-full md:w-auto">
                            <select id="finance-month-selector" class="w-full md:w-48 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white"></select>
                            <div class="flex flex-row-reverse flex-wrap gap-2 w-full md:w-auto justify-end">
                                <button class="btn-secondary font-bold py-2 px-4 rounded-lg flex items-center uppercase flex-shrink-0" onclick="showFinancesPanel()">
    <i data-lucide="plus" class="w-5 h-5 mr-2"></i> ENTRADA
</button>
                                </div>
                        </div>
                    </div>
                    
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
    <div class="stat-card bg-white p-6 rounded-xl shadow-md flex items-center space-x-4 border-l-4 border-[var(--color-highlight)]">
        <i data-lucide="trending-up" class="w-12 h-12 text-gray-700"></i>
        <div>
            <h3 class="text-lg font-extrabold text-gray-500 mb-1">INGRESOS TOTALES</h3>
            <p id="finance-total-income" class="text-5xl font-bold text-[var(--color-highlight)]">$0.00</p>
            <p id="finance-income-comparison" class="text-sm text-gray-400">&nbsp;</p>
        </div>
    </div>

    <div class="stat-card bg-white p-6 rounded-xl shadow-md flex items-center space-x-4 border-l-4 border-[var(--color-secondary)]">
        <i data-lucide="trending-down" class="w-12 h-12 text-gray-700"></i>
        <div>
            <h3 class="text-lg font-extrabold text-gray-500 mb-1">GASTOS TOTALES</h3>
            <p id="finance-total-expense" class="text-5xl font-bold text-[var(--color-secondary)]">$0.00</p>
            <p id="finance-expense-comparison" class="text-sm text-gray-400">&nbsp;</p>
        </div>
    </div>

    <div class="stat-card bg-white p-6 rounded-xl shadow-md flex items-center space-x-4 border-l-4 border-[var(--color-primary)]">
        <i data-lucide="wallet" class="w-12 h-12 text-gray-700"></i>
        <div>
            <h3 class="text-lg font-extrabold text-gray-500 mb-1">GANANCIA NETA</h3>
            <p id="finance-net-profit" class="text-5xl font-bold text-[var(--color-primary)]">$0.00</p>
            <p id="finance-profit-comparison" class="text-sm text-gray-400">&nbsp;</p>
        </div>
    </div>
</div>

                    <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
                        <div class="lg:col-span-1 bg-slate-50 rounded-xl p-6 flex flex-col items-center justify-center"><h4 class="text-lg font-extrabold text-gray-700 mb-4 uppercase flex items-center gap-2"><i data-lucide="pie-chart" class="w-5 h-5 text-[var(--color-primary)]"></i> BALANCE DEL MES</h4><div class="w-48 h-48 mb-4"><canvas id="financeDoughnutChart"></canvas></div></div>
                        <div class="lg:col-span-2"><h4 class="text-lg font-extrabold text-gray-700 mb-4 flex items-center gap-2"><i data-lucide="list-checks" class="w-5 h-5 text-[var(--color-primary)]"></i> TRANSACCIONES DEL MES</h4><div id="transaction-list" class="space-y-3 max-h-[400px] overflow-y-auto pr-2"></div></div>
                    </div>

                    <div class="mt-8">
                        <h4 class="text-xl font-extrabold text-gray-800 mb-4 flex items-center gap-2"><i data-lucide="table" class="w-6 h-6 text-[var(--color-primary)]"></i> RESUMEN HISTÓRICO</h4>
                        <div class="overflow-x-auto">
                            <table class="min-w-full bg-white rounded-lg shadow-sm overflow-hidden responsive-table-stack">
                                <thead class="bg-gray-50"><tr class="text-left text-gray-500 uppercase text-sm"><th class="py-3 px-6 font-semibold">MES</th><th class="py-3 px-6 font-semibold text-right">INGRESOS</th><th class="py-3 px-6 font-semibold text-right">GASTOS</th><th class="py-3 px-6 font-semibold text-right">GANANCIA NETA</th></tr></thead>
                                <tbody class="text-gray-700 text-sm" id="finance-summary-table-body"></tbody>
                            </table>
                        </div>
                    </div>

                    <div class="mt-8">
                        <h4 class="text-xl font-extrabold text-gray-800 mb-4 flex items-center gap-2">
                            <i data-lucide="repeat" class="w-6 h-6 text-[var(--color-primary)]"></i> GESTIÓN DE GASTOS RECURRENTES
                        </h4>
                        <div class="overflow-x-auto">
                            <table class="min-w-full bg-white rounded-lg shadow-sm overflow-hidden responsive-table-stack">
                                <thead class="bg-gray-50">
                                    <tr class="text-left text-gray-500 uppercase text-sm">
                                        <th class="py-3 px-6 font-semibold">DESCRIPCIÓN</th>
                                        <th class="py-3 px-6 font-semibold text-right">MONTO</th>
                                        <th class="py-3 px-6 font-semibold text-center">DÍA DE PAGO</th>
                                        <th class="py-3 px-6 font-semibold">CLIENTE</th>
                                        <th class="py-3 px-6 font-semibold text-center">ACCIONES</th>
                                    </tr>
                                </thead>
                                <tbody class="text-gray-700 text-sm" id="recurring-expenses-table-body">
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </main>
</div>

<section id="addFinancesPanel" class="hidden">
    <div id="finances-panel-overlay" class="fixed inset-0 bg-black bg-opacity-50 z-40"></div>
    <div id="finances-panel" class="fixed inset-y-0 right-0 w-full md:w-1/3 bg-white shadow-xl z-50 transform translate-x-full transition-transform duration-300 ease-in-out">
        <div class="flex flex-col h-full">
            <div class="bg-slate-800 text-white p-6 flex justify-between items-center flex-shrink-0">
                <div class="flex items-center">
                    <i data-lucide="wallet" class="w-6 h-6 mr-3 text-[var(--color-highlight)]"></i>
                    <h3 class="text-xl font-bold uppercase">REGISTRAR TRANSACCIÓN</h3>
                </div>
                <button onclick="hideFinancesPanel()" class="text-gray-400 hover:text-gray-200"><i data-lucide="x" class="w-6 h-6"></i></button>
            </div>
            <div class="p-6 overflow-y-auto space-y-6 flex-grow">
                <form id="add-transaccion-form">
                    <div class="mb-4 relative"><label for="transaccion-cliente-display" class="block text-gray-700 text-sm font-bold mb-2 uppercase">CLIENTE (OPCIONAL)</label><input type="text" id="transaccion-cliente-display" placeholder="Buscar Cliente..." class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white"><input type="hidden" id="transaccion-cliente"><div id="transaccion-cliente-suggestions" class="autocomplete-suggestions hidden"></div><p id="transaccion-cliente-info" class="text-xs text-gray-500 mt-1"></p></div>
                    <div class="mb-4"><label for="transaccion-tipo" class="block text-gray-700 text-sm font-bold mb-2 uppercase">TIPO</label><select id="transaccion-tipo" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white"><option value="ingreso">INGRESO</option><option value="gasto">GASTO</option></select></div>
                    <div id="recurring-options-container" class="mb-4 hidden"><div class="flex items-center mb-2"><input type="checkbox" id="is-recurring-expense" class="h-4 w-4 text-[var(--color-primary)] border-gray-300 rounded focus:ring-[var(--color-highlight)]"><label for="is-recurring-expense" class="ml-2 block text-gray-700 text-sm font-bold uppercase">GASTO RECURRENTE (TODOS LOS MESES)</label></div><div id="recurrence-day-group" class="mb-4 hidden"><label for="recurrence-day" class="block text-gray-700 text-sm font-bold mb-2 uppercase">DÍA DEL MES (1-31)</label><input type="number" id="recurrence-day" min="1" max="31" value="1" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]"></div></div>
                    <div class="mb-4"><label for="transaccion-descripcion" class="block text-gray-700 text-sm font-bold mb-2 uppercase">DESCRIPCIÓN</label><input type="text" id="transaccion-descripcion" class="w-full p-3 border border-gray-300 rounded-lg" required></div>
                    <div class="mb-4"><label for="transaccion-monto" class="block text-gray-700 text-sm font-bold mb-2 uppercase">MONTO</label><input type="number" step="0.01" id="transaccion-monto" class="w-full p-3 border border-gray-300 rounded-lg" required></div>
                    <div id="recurrence-start-date-group-add" class="mb-4"><label for="transaccion-fecha" class="block text-gray-700 text-sm font-bold mb-2 uppercase" id="transaccion-fecha-label-add">FECHA</label><input type="date" id="transaccion-fecha" class="w-full p-3 border border-gray-300 rounded-lg" required></div>
                    <div id="recurrence-end-date-group-add" class="mb-6 hidden"><label for="transaccion-end-date" class="block text-gray-700 text-sm font-bold mb-2 uppercase">FECHA DE FIN (OPCIONAL)</label><input type="date" id="transaccion-end-date" class="w-full p-3 border border-gray-300 rounded-lg"></div>
                    <div class="flex flex-col sm:flex-row justify-end space-y-2 sm:space-y-0 sm:space-x-4 mt-4">
                        <button type="button" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase w-full sm:w-auto" onclick="hideFinancesPanel()">CANCELAR</button>
                        <button type="submit" class="btn-secondary font-bold py-2 px-4 rounded-lg uppercase w-full sm:w-auto">GUARDAR</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</section>

<section id="editFinancesPanel" class="hidden">
    <div id="edit-finances-panel-overlay" class="fixed inset-0 bg-black bg-opacity-50 z-40"></div>
    <div id="edit-finances-panel" class="fixed inset-y-0 right-0 w-full md:w-1/3 bg-white shadow-xl z-50 transform translate-x-full transition-transform duration-300 ease-in-out">
        <div class="flex flex-col h-full">
            <div class="bg-slate-800 text-white p-6 flex justify-between items-center flex-shrink-0">
                <div class="flex items-center">
                    <i data-lucide="pencil-ruler" class="w-6 h-6 mr-3 text-[var(--color-highlight)]"></i>
                    <h3 class="text-xl font-bold uppercase">EDITAR TRANSACCIÓN</h3>
                </div>
                <button onclick="hideEditFinancesPanel()" class="text-gray-400 hover:text-gray-200"><i data-lucide="x" class="w-6 h-6"></i></button>
            </div>
            <div class="p-6 overflow-y-auto space-y-6 flex-grow">
                <form id="view-transaccion-form">
                    <input type="hidden" id="view-transaccion-id">
                    <input type="hidden" id="currentTransactionIsRecurring">
                    <div class="mb-4 relative"><label for="view-transaccion-cliente-display" class="block text-gray-700 text-sm font-bold mb-2 uppercase">CLIENTE</label><input type="text" id="view-transaccion-cliente-display" placeholder="Buscar Cliente..." class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)] bg-white"><input type="hidden" id="view-transaccion-cliente"><div id="view-transaccion-cliente-suggestions" class="autocomplete-suggestions hidden"></div><p id="view-transaccion-cliente-info" class="text-xs text-gray-500 mt-1"></p></div>
                    <div class="mb-4"><label for="view-transaccion-tipo" class="block text-gray-700 text-sm font-bold mb-2 uppercase">TIPO</label><select id="view-transaccion-tipo" class="w-full p-3 border border-gray-300 rounded-lg bg-white"><option value="ingreso">INGRESO</option><option value="gasto">GASTO</option></select></div>
                    <div id="view-recurring-options-container" class="mb-4 hidden"><div class="flex items-center mb-2"><input type="checkbox" id="view-is-recurring-expense" class="h-4 w-4 text-[var(--color-primary)] border-gray-300 rounded focus:ring-[var(--color-highlight)]" disabled><label for="view-is-recurring-expense" class="ml-2 block text-gray-700 text-sm font-bold uppercase">GASTO RECURRENTE</label></div><div id="view-recurrence-day-group" class="mb-4 hidden"><label for="view-recurrence-day" class="block text-gray-700 text-sm font-bold mb-2 uppercase">DÍA DEL MES (1-31)</label><input type="number" id="view-recurrence-day" min="1" max="31" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]"></div><div id="view-recurrence-start-date-group" class="mb-4 hidden"><label for="view-recurrence-start-date" class="block text-gray-700 text-sm font-bold mb-2 uppercase">FECHA DE INICIO</label><input type="date" id="view-recurrence-start-date" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-highlight)]"></div><div id="view-recurrence-end-date-group" class="mb-4 hidden"><label for="view-recurrence-end-date" class="block text-gray-700 text-sm font-bold mb-2 uppercase">FECHA DE FIN (OPCIONAL)</label><input type="date" id="view-transaccion-end-date" class="w-full p-3 border border-gray-300 rounded-lg"></div></div>
                    <div class="mb-4"><label for="view-transaccion-descripcion" class="block text-gray-700 text-sm font-bold mb-2 uppercase">DESCRIPCIÓN</label><input type="text" id="view-transaccion-descripcion" class="w-full p-3 border border-gray-300 rounded-lg" required></div>
                    <div class="mb-4"><label for="view-transaccion-monto" class="block text-gray-700 text-sm font-bold mb-2 uppercase">MONTO</label><input type="number" step="0.01" id="view-transaccion-monto" class="w-full p-3 border border-gray-300 rounded-lg" required></div>
                    <div class="mb-6"><label for="view-transaccion-fecha" class="block text-gray-700 text-sm font-bold mb-2 uppercase">FECHA</label><input type="date" id="view-transaccion-fecha" class="w-full p-3 border border-gray-300 rounded-lg" required></div>
                    <div class="flex flex-col sm:flex-row justify-end space-y-2 sm:space-y-0 sm:space-x-4 mt-4">
                        <button type="button" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase w-full sm:w-auto" onclick="hideEditFinancesPanel()">CANCELAR</button>
                        <button type="submit" class="btn-primary font-bold py-2 px-4 rounded-lg uppercase w-full sm:w-auto" id="save-transaction-changes-btn">GUARDAR CAMBIOS</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</section>

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

<script>
    document.addEventListener('DOMContentLoaded', function() {

        // =================================================================
        // INYECCIÓN DE DATOS DESDE PHP (NO MODIFICAR)
        // =================================================================
        let allTransactions = <?php echo $transactions_json; ?>;
        let allRecurringExpenses = <?php echo $recurring_expenses_json; ?>;
        let allClients = [];

        // =================================================================
        // VARIABLES Y CACHÉ DE ELEMENTOS DEL DOM
        // =================================================================
        const DOMElements = {
            // General
            mobileMenuButton: document.getElementById('mobile-menu-button'),
            sidebar: document.getElementById('sidebar'),
            sidebarOverlay: document.getElementById('sidebar-overlay'),
            confirmDeleteButton: document.getElementById('confirm-delete-button'),
            confirmItemTypeSpan: document.getElementById('confirm-item-type'),
            phoneInput: document.getElementById('contact_phone'),

            // Finanzas
            financeMonthSelector: document.getElementById('finance-month-selector'),
            transactionList: document.getElementById('transaction-list'),
            financeDoughnutChart: document.getElementById('financeDoughnutChart'),
            financeSummaryTableBody: document.getElementById('finance-summary-table-body'),
            recurringExpensesTableBody: document.getElementById('recurring-expenses-table-body'),

            // Paneles de Agregar
            addFinancesPanel: document.getElementById('addFinancesPanel'),
            financesPanel: document.getElementById('finances-panel'),
            financesPanelOverlay: document.getElementById('finances-panel-overlay'),
            addTransaccionForm: document.getElementById('add-transaccion-form'),
            transaccionTipo: document.getElementById('transaccion-tipo'),
            recurringOptionsContainer: document.getElementById('recurring-options-container'),
            isRecurringExpenseCheckbox: document.getElementById('is-recurring-expense'),
            transaccionFechaInput: document.getElementById('transaccion-fecha'),
            transaccionFechaLabelAdd: document.getElementById('transaccion-fecha-label-add'),
            recurrenceEndDateGroupAdd: document.getElementById('recurrence-end-date-group-add'),
            recurrenceDayGroup: document.getElementById('recurrence-day-group'),
            recurrenceDayInput: document.getElementById('recurrence-day'),

            // Paneles de Editar
            editFinancesPanel: document.getElementById('editFinancesPanel'),
            editFinancesPanelInner: document.getElementById('edit-finances-panel'),
            editFinancesPanelOverlay: document.getElementById('edit-finances-panel-overlay'),
            viewTransaccionForm: document.getElementById('view-transaccion-form')
        };
        
        let financeChartInstance;

        // =================================================================
        // FUNCIONES DE UTILIDAD (UI, MODALES, ETC.)
        // =================================================================

        /**
         * Maneja las notificaciones Toast globales.
         */
        function handleGlobalNotifications() {
            const urlParams = new URLSearchParams(window.location.search);
            const notificationType = urlParams.get('notification_type');
            const notificationMessage = urlParams.get('notification_message');
            if (notificationType && notificationMessage) {
                if (typeof showToast === 'function') {
                    showToast(notificationMessage, notificationType);
                } else {
                    console.error("showToast function is not defined. Toast notification might not display.");
                }
            }
        }

        /**
         * Alterna la visibilidad del sidebar móvil.
         */
        function toggleSidebar() {
            DOMElements.sidebar.classList.toggle('-translate-x-full');
            DOMElements.sidebarOverlay.classList.toggle('hidden');
        }

        /**
         * Formatea un número de teléfono.
         */
        function formatPhoneNumber(phoneNumberString) {
            if (!phoneNumberString) return '';
            const cleaned = ('' + phoneNumberString).replace(/\D/g, '');
            const match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
            return match ? `(${match[1]}) ${match[2]}-${match[3]}` : phoneNumberString;
        }

        /**
         * Muestra un panel lateral.
         */
        window.showFinancesPanel = function() {
            DOMElements.addFinancesPanel.classList.remove('hidden');
            DOMElements.financesPanel.classList.remove('translate-x-full');
            DOMElements.financesPanelOverlay.classList.remove('hidden');
            document.body.style.overflow = 'hidden';

            DOMElements.addTransaccionForm.reset();
            document.getElementById('transaccion-cliente-display').value = '';
            document.getElementById('transaccion-cliente').value = '';
            document.getElementById('transaccion-cliente-info').textContent = '';

            DOMElements.transaccionTipo.value = 'ingreso';
            DOMElements.recurringOptionsContainer.classList.add('hidden');
            DOMElements.isRecurringExpenseCheckbox.checked = false;
            DOMElements.transaccionFechaLabelAdd.textContent = 'FECHA';
            DOMElements.transaccionFechaInput.value = new Date().toISOString().slice(0, 10);

            if (typeof lucide !== 'undefined') {
                lucide.createIcons();
            }
        }
        
        /**
         * Oculta un panel lateral.
         */
        window.hideFinancesPanel = function() {
            DOMElements.financesPanel.classList.add('translate-x-full');
            setTimeout(() => {
                DOMElements.addFinancesPanel.classList.add('hidden');
                DOMElements.financesPanelOverlay.classList.add('hidden');
                document.body.style.overflow = '';
            }, 300);
        }

        /**
         * Muestra el panel de edición.
         */
        function showEditFinancesPanel() {
            DOMElements.editFinancesPanel.classList.remove('hidden');
            DOMElements.editFinancesPanelInner.classList.remove('translate-x-full');
            DOMElements.editFinancesPanelOverlay.classList.remove('hidden');
            document.body.style.overflow = 'hidden';
            if (typeof lucide !== 'undefined') {
                lucide.createIcons();
            }
        }

        /**
         * Oculta el panel de edición.
         */
        window.hideEditFinancesPanel = function() {
            DOMElements.editFinancesPanelInner.classList.add('translate-x-full');
            setTimeout(() => {
                DOMElements.editFinancesPanel.classList.add('hidden');
                DOMElements.editFinancesPanelOverlay.classList.add('hidden');
                document.body.style.overflow = '';
            }, 300);
        }

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

        /**
         * Cierra un modal de forma controlada.
         */
        window.closeModal = (modalId) => {
            const modal = document.getElementById(modalId);
            if (!modal) {
                showToast(`Error: Modal con ID "${modalId}" no encontrado para cerrar.`, 'error');
                return;
            }
            const modalBox = modal.querySelector('div:first-of-type');
            modalBox.classList.add('scale-95', 'opacity-0');
            setTimeout(() => {
                modal.classList.add('hidden');
                document.body.style.overflow = '';
            }, 300);
        };
        
        /**
         * Abre el modal de confirmación de eliminación con la lógica correcta.
         */
        window.openConfirmDeleteModal = (itemId, itemType) => {
            DOMElements.confirmDeleteButton.dataset.itemId = itemId;
            DOMElements.confirmItemTypeSpan.textContent = (itemType === 'recurrente' ? 'GASTO RECURRENTE' : 'TRANSACCIÓN');
            
            DOMElements.confirmDeleteButton.onclick = async () => {
                if (itemType === 'recurrente') await deleteRecurringExpense(itemId);
                else await deleteTransaction(itemId);
            };

            window.openModal('confirmDeleteModal');
        };

        /**
         * Abre el panel de edición de transacciones.
         */
        window.openViewTransaccionModal = (transactionId, isRecurringTransaction = false) => {
            let transaction = isRecurringTransaction ? allRecurringExpenses.find(t => t.id == transactionId) : allTransactions.find(t => t.id == transactionId);
            if (!transaction) {
                showToast('Transacción no encontrada.', 'error');
                return;
            }

            document.getElementById('view-transaccion-id').value = transaction.id;
            document.getElementById('view-transaccion-tipo').value = transaction.type;
            document.getElementById('view-transaccion-descripcion').value = transaction.description;
            document.getElementById('view-transaccion-monto').value = transaction.amount;
            document.getElementById('view-transaccion-fecha').value = transaction.transaction_date || transaction.start_date;
            document.getElementById('currentTransactionIsRecurring').value = isRecurringTransaction;
            
            const viewTransaccionClienteDisplay = document.getElementById('view-transaccion-cliente-display');
            const viewTransaccionClienteInput = document.getElementById('view-transaccion-cliente');
            const viewTransaccionClienteInfo = document.getElementById('view-transaccion-cliente-info');

            if (transaction.client_id) {
                const client = allClients.find(c => c.id == transaction.client_id);
                viewTransaccionClienteDisplay.value = client?.name || '';
                viewTransaccionClienteInput.value = transaction.client_id;
                viewTransaccionClienteInfo.textContent = client ? `Email: ${client.email || 'N/A'} | Tel: ${formatPhoneNumber(client.phone || client.mobile) || 'N/A'}` : '';
            } else {
                viewTransaccionClienteDisplay.value = '';
                viewTransaccionClienteInput.value = '';
                viewTransaccionClienteInfo.textContent = '';
            }
            
            const viewRecurringOptionsContainer = document.getElementById('view-recurring-options-container');
            const viewTransaccionFechaGroup = document.getElementById('view-transaccion-fecha').parentElement;
            
            if (isRecurringTransaction) {
                viewRecurringOptionsContainer.classList.remove('hidden');
                viewTransaccionFechaGroup.classList.add('hidden');
                document.getElementById('view-recurrence-day').value = transaction.recurrence_day_of_month;
                document.getElementById('view-recurrence-start-date').value = transaction.start_date;
                document.getElementById('view-transaccion-end-date').value = transaction.end_date || '';
            } else {
                viewRecurringOptionsContainer.classList.add('hidden');
                viewTransaccionFechaGroup.classList.remove('hidden');
            }

            showEditFinancesPanel();
        };

        function reloadData() {
            location.reload();
        }

        // =================================================================
        // FUNCIONES DE RENDERIZADO Y CÁLCULO
        // =================================================================

        /**
         * Configura el selector de meses con los meses que tienen transacciones.
         */
        function setupFinanceMonthSelector() {
            const months = new Set();
            allTransactions.forEach(t => months.add(t.transaction_date.substring(0, 7)));
            const currentMonth = new Date().toISOString().substring(0, 7);
            months.add(currentMonth);

            const sortedMonths = Array.from(months).sort().reverse();
            DOMElements.financeMonthSelector.innerHTML = '';
            sortedMonths.forEach(month => {
                const option = document.createElement('option');
                option.value = month;
                const [year, monthNum] = month.split('-');
                option.textContent = new Date(year, monthNum - 1, 1).toLocaleString('es-ES', { month: 'long', year: 'numeric' }).toUpperCase();
                DOMElements.financeMonthSelector.appendChild(option);
            });
            if (sortedMonths.length > 0) DOMElements.financeMonthSelector.value = sortedMonths[0];
        }
        
        /**
         * Renderiza la lista de transacciones y el gráfico del mes seleccionado.
         */
        function renderFinances() {
            const selectedMonth = DOMElements.financeMonthSelector.value;
            if (!selectedMonth) return;

            const [year, month] = selectedMonth.split('-').map(Number);
            const selectedMonthStart = new Date(year, month - 1, 1);
            const selectedMonthEnd = new Date(year, month, 0);

            let totalIncome = 0;
            let totalExpense = 0;
            const displayTransactions = [];

            // Transacciones únicas (incluye los gastos recurrentes ya generados)
            allTransactions.filter(t => t.transaction_date.startsWith(selectedMonth)).forEach(t => {
                if (t.type === 'ingreso') totalIncome += parseFloat(t.amount);
                else totalExpense += parseFloat(t.amount);
                displayTransactions.push(t);
            });

            // Gastos recurrentes que NO han sido registrados en la tabla 'finances'
            allRecurringExpenses.forEach(recurring => {
                const startDate = new Date(`${recurring.start_date}T00:00:00`);
                const endDate = recurring.end_date ? new Date(`${recurring.end_date}T00:00:00`) : null;
                const isActive = startDate <= selectedMonthEnd && (!endDate || endDate >= selectedMonthStart);

                // Comprobar si ya existe una transacción con una descripción similar en este mes.
                // Esta es la clave para evitar la duplicación.
                const isAlreadyAdded = displayTransactions.some(t => 
                    t.description.includes(recurring.description) && 
                    t.transaction_date.startsWith(selectedMonth)
                );

                if (isActive && !isAlreadyAdded) {
                    totalExpense += parseFloat(recurring.amount);
                    const dayOfMonth = String(recurring.recurrence_day_of_month).padStart(2, '0');
                    displayTransactions.push({
                        id: `recurring-${recurring.id}`,
                        type: 'gasto',
                        description: recurring.description,
                        amount: recurring.amount,
                        transaction_date: `${selectedMonth}-${dayOfMonth}`,
                        client_name: recurring.client_name,
                        is_recurring_instance: true
                    });
                }
            });

            displayTransactions.sort((a, b) => new Date(b.transaction_date) - new Date(a.transaction_date));
            
            DOMElements.transactionList.innerHTML = displayTransactions.length === 0 ?
                `<p class="text-gray-500 text-center uppercase">NO HAY TRANSACCIONES PARA ESTE MES.</p>` :
                displayTransactions.map(t => {
                    const isIncome = t.type === 'ingreso';
                    const clientInfo = t.client_name ? `<p class="text-xs text-blue-600 font-semibold">${t.client_name}</p>` : '';
                    const recurringTag = t.is_recurring_instance || (t.description.includes('(Recurrente)') && !t.is_recurring_instance) ? `<span class="recurring-tag !ml-0 !mr-2">RECURRENTE</span>` : '';
                    const actionsHTML = t.is_recurring_instance ? '' : `
                        <div class="flex items-center justify-center space-x-2 mt-1 opacity-0 group-hover:opacity-100 transition-opacity">
                            <button class="text-gray-400 hover:text-blue-600" onclick="window.openViewTransaccionModal(${t.id}, false)"><i data-lucide="edit-2" class="w-4 h-4"></i></button>
                            <button class="text-gray-400 hover:text-[var(--color-secondary)]" onclick="window.openConfirmDeleteModal(${t.id}, 'transaccion')"><i data-lucide="trash-2" class="w-4 h-4"></i></button>
                        </div>`;
                    return `
                        <div class="transaction-card flex items-center p-3 rounded-lg group ${isIncome ? 'bg-green-50' : 'bg-white'}">
                            <div class="rounded-full p-2 mr-4 ${isIncome ? 'bg-green-200' : 'bg-[var(--color-secondary)]'}"><i data-lucide="${isIncome ? 'arrow-up-right' : 'arrow-down-left'}" class="w-5 h-5 ${isIncome ? 'text-green-700' : 'text-white'}"></i></div>
                            <div class="flex-grow">
                                <p class="font-bold text-gray-800 uppercase flex items-center">${recurringTag}${t.description.replace(' (Recurrente)', '')}</p>
                                ${clientInfo}
                                <p class="text-sm text-gray-500">${t.transaction_date}</p>
                            </div>
                            <div class="text-right">
                                <p class="font-bold ${isIncome ? 'text-green-600' : 'text-[var(--color-secondary)]'}">${isIncome ? '+' : '-'}$${parseFloat(t.amount).toFixed(2)}</p>
                                ${actionsHTML}
                            </div>
                        </div>`;
                }).join('');

            document.getElementById('finance-total-income').textContent = `$${totalIncome.toFixed(2)}`;
            document.getElementById('finance-total-expense').textContent = `$${totalExpense.toFixed(2)}`;
            document.getElementById('finance-net-profit').textContent = `$${(totalIncome - totalExpense).toFixed(2)}`;

            if (financeChartInstance) financeChartInstance.destroy();
            financeChartInstance = new Chart(DOMElements.financeDoughnutChart.getContext('2d'), {
                type: 'doughnut',
                data: { datasets: [{ data: [totalIncome > 0 ? totalIncome : 0.01, totalExpense > 0 ? totalExpense : 0.01], backgroundColor: ['#16a34a', '#dc2626'], borderColor: '#fff', borderWidth: 4 }] },
                options: { responsive: true, maintainAspectRatio: false, cutout: '70%', plugins: { legend: { display: false } } }
            });

            renderFinanceSummaryTable();
            if (typeof lucide !== 'undefined') {
                lucide.createIcons();
            }
        }
        
        /**
         * Renderiza la tabla de resumen financiero.
         */
        function renderFinanceSummaryTable() {
            const monthlySummaries = {};
            allTransactions.forEach(t => {
                const month = t.transaction_date.substring(0, 7);
                if (!monthlySummaries[month]) monthlySummaries[month] = { income: 0, expense: 0 };
                if (t.type === 'ingreso') monthlySummaries[month].income += parseFloat(t.amount);
                else monthlySummaries[month].expense += parseFloat(t.amount);
            });
            
            Object.keys(monthlySummaries).forEach(monthKey => {
                const [year, month] = monthKey.split('-').map(Number);
                const monthStart = new Date(year, month - 1, 1);
                const monthEnd = new Date(year, month, 0);

                allRecurringExpenses.forEach(recurring => {
                    const startDate = new Date(`${recurring.start_date}T00:00:00`);
                    const endDate = recurring.end_date ? new Date(`${recurring.end_date}T00:00:00`) : null;
                    const isActive = startDate <= monthEnd && (!endDate || endDate >= monthStart);

                    // De manera similar, revisar si el gasto recurrente ya fue registrado
                    const isAlreadyCounted = allTransactions.some(t => 
                        t.description.includes(recurring.description) && 
                        t.transaction_date.startsWith(monthKey)
                    );

                    if (isActive && !isAlreadyCounted) {
                        monthlySummaries[monthKey].expense += parseFloat(recurring.amount);
                    }
                });
            });

            const sortedMonths = Object.keys(monthlySummaries).sort().reverse();
            DOMElements.financeSummaryTableBody.innerHTML = '';
            sortedMonths.forEach(month => {
                const summary = monthlySummaries[month];
                const net = summary.income - summary.expense;
                const monthName = new Date(`${month}-02T00:00:00`).toLocaleString('es-ES', { month: 'long', year: 'numeric' }).toUpperCase();
                const row = DOMElements.financeSummaryTableBody.insertRow();
                row.innerHTML = `
                    <td class="py-4 px-6 font-semibold" data-label="MES">${monthName}</td>
                    <td class="py-4 px-6 text-right text-green-600 font-bold" data-label="INGRESOS">$${summary.income.toFixed(2)}</td>
                    <td class="py-4 px-6 text-right text-[var(--color-secondary)] font-bold" data-label="GASTOS">$${summary.expense.toFixed(2)}</td>
                    <td class="py-4 px-6 text-right font-bold ${net >= 0 ? 'text-blue-700' : 'text-[var(--color-secondary)]'}" data-label="GANANCIA NETA">$${net.toFixed(2)}</td>
                `;
            });
        }

        /**
         * Renderiza la tabla de gastos recurrentes.
         */
        function renderRecurringExpensesTable() {
            DOMElements.recurringExpensesTableBody.innerHTML = '';
            if (allRecurringExpenses.length === 0) {
                DOMElements.recurringExpensesTableBody.innerHTML = `<tr><td colspan="5" class="text-center py-4 text-gray-500 uppercase">No tienes gastos recurrentes configurados.</td></tr>`;
                return;
            }
            allRecurringExpenses.forEach(exp => {
                const row = DOMElements.recurringExpensesTableBody.insertRow();
                row.className = 'border-b border-gray-200 hover:bg-gray-50';
                const clientName = exp.client_name || '<span class="text-gray-400">N/A</span>';
                row.innerHTML = `
                    <td class="py-4 px-6 font-semibold" data-label="DESCRIPCIÓN">${exp.description}</td>
                    <td class="py-4 px-6 text-right font-bold text-[var(--color-secondary)]" data-label="MONTO">$${parseFloat(exp.amount).toFixed(2)}</td>
                    <td class="py-4 px-6 text-center" data-label="DÍA DE PAGO">${exp.recurrence_day_of_month}</td>
                    <td class="py-4 px-6" data-label="CLIENTE">${clientName}</td>
                    <td class="py-4 px-6 text-center actions-cell" data-label="ACCIONES">
                        <div class="flex flex-col sm:flex-row items-center justify-center space-y-2 sm:space-y-0 sm:space-x-2">
                            <button class="text-gray-400 hover:text-blue-600 w-full sm:w-auto" title="Editar Regla" onclick="window.openViewTransaccionModal(${exp.id}, true)"><i data-lucide="edit-2" class="w-4 h-4"></i></button>
                            <button class="text-gray-400 hover:text-[var(--color-secondary)] w-full sm:w-auto" title="Eliminar Regla Permanentemente" onclick="window.openConfirmDeleteModal(${exp.id}, 'recurrente')"><i data-lucide="trash-2" class="w-4 h-4"></i></button>
                        </div>
                    </td>`;
            });
            if (typeof lucide !== 'undefined') {
                lucide.createIcons();
            }
        }

        // =================================================================
        // LÓGICA DE INTERACCIÓN CON EL SERVIDOR
        // =================================================================

        /**
         * Elimina una transacción a través de la API.
         */
        async function deleteTransaction(transactionId) {
        try {
            const response = await fetch('db/finances-delete.php', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({ id: transactionId })
            });
            const result = await response.json();
            if (result.success) {
                window.closeModal('confirmDeleteModal');
                showToast('Transacción eliminada con éxito.', 'success');
                
                allTransactions = allTransactions.filter(t => t.id != transactionId);
                renderFinances();

            } else {
                throw new Error(result.message || 'El servidor indicó un error.');
            }
        } catch (error) {
            console.error("Error en deleteTransaction:", error);
            showToast(error.message || 'Error de conexión al eliminar la transacción.', 'error');
        }
    }

        /**
         * Elimina un gasto recurrente a través de la API.
         */
        async function deleteRecurringExpense(recurringExpenseId) {
        try {
            const response = await fetch('db/recurring-finances-delete.php', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({ id: recurringExpenseId })
            });
            const result = await response.json();
            if (result.success) {
                window.closeModal('confirmDeleteModal');
                showToast('Gasto recurrente eliminado con éxito.', 'success');

                allRecurringExpenses = allRecurringExpenses.filter(t => t.id != recurringExpenseId);

                renderFinances(); 
                renderRecurringExpensesTable();

            } else {
                throw new Error(result.message || 'El servidor indicó un error.');
            }
        } catch (error) {
            console.error("Error en deleteRecurringExpense:", error);
            showToast(error.message || 'Error de conexión al eliminar el gasto recurrente.', 'error');
        }
    }

        /**
         * Obtiene todos los clientes de la API.
         */
        async function fetchAllClients() {
            try {
                const response = await fetch('db/clients-read-contact-data.php');
                const result = await response.json();
                if (result.success) {
                    allClients = result.data;
                } else {
                    showToast("Error al cargar clientes: " + (result.message || 'Error desconocido.'), 'error');
                }
            } catch (error) {
                showToast("Error de conexión al cargar clientes.", 'error');
            }
        }
        
        /**
         * Configura el autocompletado para los campos de cliente.
         */
        const setupClientAutocomplete = (displayInput, hiddenInput, suggestionsDiv, infoDisplay) => {
            let blurTimeout;
            displayInput.addEventListener('input', async function() {
                clearTimeout(blurTimeout);
                const searchTerm = this.value.toLowerCase();
                suggestionsDiv.innerHTML = '';
                hiddenInput.value = '';
                infoDisplay.textContent = '';
                if (searchTerm.length < 2) {
                    suggestionsDiv.classList.add('hidden');
                    return;
                }
                const filteredClients = allClients.filter(client =>
                    client.name.toLowerCase().includes(searchTerm) ||
                    (client.email && client.email.toLowerCase().includes(searchTerm))
                );
                if (filteredClients.length > 0) {
                    suggestionsDiv.innerHTML = filteredClients.map(client => `
                        <div class="autocomplete-suggestion-item p-2 cursor-pointer hover:bg-gray-100 border-b border-gray-200 last:border-b-0" data-client-id="${client.id}">
                            ${client.name} (${client.email || 'N/A'})
                        </div>`).join('');
                    suggestionsDiv.classList.remove('hidden');
                } else {
                    suggestionsDiv.classList.add('hidden');
                }
            });
            displayInput.addEventListener('focus', function() {
                if (this.value.length >= 2) this.dispatchEvent(new Event('input'));
            });
            displayInput.addEventListener('blur', () => {
                blurTimeout = setTimeout(() => { suggestionsDiv.classList.add('hidden'); }, 150);
            });
            suggestionsDiv.addEventListener('mousedown', function(e) {
                e.preventDefault();
                const suggestionItem = e.target.closest('.autocomplete-suggestion-item');
                if (suggestionItem) {
                    const clientId = suggestionItem.dataset.clientId;
                    const client = allClients.find(c => c.id == clientId);
                    displayInput.value = client.name;
                    hiddenInput.value = client.id;
                    infoDisplay.textContent = `Email: ${client.email || 'N/A'} | Tel: ${formatPhoneNumber(client.phone || client.mobile) || 'N/A'}`;
                    suggestionsDiv.classList.add('hidden');
                    showToast(`Cliente "${client.name}" seleccionado.`, 'info');
                }
            });
        };

        // =================================================================
        // INICIALIZACIÓN
        // =================================================================

        // Se ejecuta al cargar el DOM
        DOMElements.mobileMenuButton.addEventListener('click', toggleSidebar);
        DOMElements.sidebarOverlay.addEventListener('click', toggleSidebar);

        if (DOMElements.phoneInput) {
            IMask(DOMElements.phoneInput, { mask: '(000) 000-0000' });
        }
        
        handleGlobalNotifications();

        DOMElements.transaccionTipo.addEventListener('change', function() {
            DOMElements.recurringOptionsContainer.classList.toggle('hidden', this.value !== 'gasto');
            if (this.value !== 'gasto') {
                DOMElements.isRecurringExpenseCheckbox.checked = false;
                DOMElements.isRecurringExpenseCheckbox.dispatchEvent(new Event('change'));
            }
        });

        DOMElements.isRecurringExpenseCheckbox.addEventListener('change', function() {
            const isChecked = this.checked;
            DOMElements.recurrenceDayGroup.classList.toggle('hidden', !isChecked);
            DOMElements.recurrenceEndDateGroupAdd.classList.toggle('hidden', !isChecked);
            DOMElements.transaccionFechaLabelAdd.textContent = isChecked ? 'FECHA DE INICIO' : 'FECHA';
            if (isChecked) {
                const dateValue = DOMElements.transaccionFechaInput.value;
                if (dateValue) {
                    const day = parseInt(dateValue.split('-')[2], 10);
                    DOMElements.recurrenceDayInput.value = day;
                }
            }
        });
        DOMElements.transaccionFechaInput.addEventListener('change', function() {
            if (DOMElements.isRecurringExpenseCheckbox.checked) {
                const day = parseInt(this.value.split('-')[2], 10);
                DOMElements.recurrenceDayInput.value = day;
            }
        });

        DOMElements.addTransaccionForm.addEventListener('submit', async (e) => {
            e.preventDefault();
            // ... (tu código para construir transactionData es correcto)
            const isRecurring = DOMElements.transaccionTipo.value === 'gasto' && DOMElements.isRecurringExpenseCheckbox.checked;
            const transactionData = {
                client_id: document.getElementById('transaccion-cliente').value || null,
                type: DOMElements.transaccionTipo.value,
                description: document.getElementById('transaccion-descripcion').value,
                amount: document.getElementById('transaccion-monto').value,
                transaction_date: DOMElements.transaccionFechaInput.value,
                is_recurring: isRecurring,
                recurrence_day_of_month: isRecurring ? DOMElements.recurrenceDayInput.value : null,
                end_date: isRecurring ? document.getElementById('transaccion-end-date').value || null : null
            };

            try {
                const response = await fetch('db/finances-create.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(transactionData) });
                const result = await response.json();
                
                if (result.success) {
                    hideFinancesPanel();
                    showToast('Transacción agregada con éxito.', 'success');
                    
                    if (result.transaction) {
                        allTransactions.unshift(result.transaction); 
                    }
                    if (result.recurring_expense) {
                        allRecurringExpenses.push(result.recurring_expense);
                        allRecurringExpenses.sort((a, b) => a.recurrence_day_of_month - b.recurrence_day_of_month);
                    }

                    setupFinanceMonthSelector(); 
                    renderFinances();
                    renderRecurringExpensesTable();

                } else {
                    showToast(result.message || 'Error al guardar.', 'error');
                }
            } catch (error) {
                showToast('Error de conexión al guardar.', 'error');
            }
        });

        DOMElements.viewTransaccionForm.addEventListener('submit', async (e) => {
            e.preventDefault();
            const transactionId = document.getElementById('view-transaccion-id').value;
            const currentIsRecurring = document.getElementById('currentTransactionIsRecurring').value === 'true';
            const updateUrl = currentIsRecurring ? 'db/recurring-finances-update.php' : 'db/finances-update.php';
            
            let updateData = {
                id: transactionId,
                description: document.getElementById('view-transaccion-descripcion').value,
                amount: document.getElementById('view-transaccion-monto').value,
                type: document.getElementById('view-transaccion-tipo').value,
                client_id: document.getElementById('view-transaccion-cliente').value || null
            };
            
            if (currentIsRecurring) {
                updateData.recurrence_day_of_month = document.getElementById('view-recurrence-day').value;
                updateData.start_date = document.getElementById('view-recurrence-start-date').value;
                updateData.end_date = document.getElementById('view-transaccion-end-date').value || null;
            } else {
                updateData.transaction_date = document.getElementById('view-transaccion-fecha').value;
            }

            try {
                const response = await fetch(updateUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(updateData) });
                const result = await response.json();
                
                if (result.success) {
                    hideEditFinancesPanel();
                    showToast('Cambios guardados con éxito.', 'success');
                    
                    if (result.transaction) { 
                        const index = allTransactions.findIndex(t => t.id == result.transaction.id);
                        if (index > -1) {
                            allTransactions[index] = result.transaction;
                        } else {
                            allTransactions.unshift(result.transaction); 
                        }
                    }
                    if (result.recurring_expense) { 
                        const index = allRecurringExpenses.findIndex(t => t.id == result.recurring_expense.id);
                        if (index > -1) {
                            allRecurringExpenses[index] = result.recurring_expense;
                        } else {
                            allRecurringExpenses.push(result.recurring_expense);
                        }
                        allRecurringExpenses.sort((a, b) => a.recurrence_day_of_month - b.recurrence_day_of_month);
                    }

                    renderFinances();
                    renderRecurringExpensesTable();

                } else {
                    showToast(result.message || 'Error al guardar cambios.', 'error');
                }
            } catch (error) {
                showToast('Error de conexión al guardar cambios.', 'error');
            }
        });

        DOMElements.financesPanelOverlay.addEventListener('click', hideFinancesPanel);
        DOMElements.editFinancesPanelOverlay.addEventListener('click', hideEditFinancesPanel);
        DOMElements.financeMonthSelector.addEventListener('change', renderFinances);

        setupClientAutocomplete(
            document.getElementById('transaccion-cliente-display'),
            document.getElementById('transaccion-cliente'),
            document.getElementById('transaccion-cliente-suggestions'),
            document.getElementById('transaccion-cliente-info')
        );

        setupClientAutocomplete(
            document.getElementById('view-transaccion-cliente-display'),
            document.getElementById('view-transaccion-cliente'),
            document.getElementById('view-transaccion-cliente-suggestions'),
            document.getElementById('view-transaccion-cliente-info')
        );

        // Inicialización
        (async () => {
            await fetchAllClients();
            setupFinanceMonthSelector();
            renderFinances();
            renderRecurringExpensesTable();
            if (typeof lucide !== 'undefined') {
                lucide.createIcons();
            }
        })();
    });
</script>
</body>
</html>