<?php
include 'files/guardiankey.php';
include_once 'db/db_connection.php';

// --- DEFINICIÓN DE FASES ---
$funnel_stages = [
    0 => ['id' => 0, 'title' => 'COMPRENDER PROBLEMA', 'db_status' => 'En Seguimiento', 'color_class' => 'text-[var(--color-primary)]', 'border_class' => 'border-l-[var(--color-primary)]', 'icon' => 'search-check', 'desc' => 'ACCIÓN: Trata De Comprender El Motivo Principal Por El Que Busca Contratarte'],
    1 => ['id' => 1, 'title' => 'PRESENTAR SOLUCIÓN', 'db_status' => 'Presentar Solución', 'color_class' => 'text-[var(--color-primary)]', 'border_class' => 'border-l-[var(--color-highlight)]', 'icon' => 'presentation', 'desc' => 'ACCIÓN: Presentar La Solución De Ese Problema Para Generar Confianza'],
    2 => ['id' => 2, 'title' => 'INTRODUCIR SERVICIO', 'db_status' => 'Introducir Servicio', 'color_class' => 'text-[var(--color-secondary)]', 'border_class' => 'border-l-[var(--color-secondary)]', 'icon' => 'package-check', 'desc' => 'ACCIÓN: Mostrar Cómo El Servicio Resuelve Esa Necesidad Y Que Tome Acción'],
];

$converted_db_status = 'Cotizacion Solicitada'; 
$lost_db_status = 'Descartado'; 
$quote_funnel_status = 'Seguimiento Post Envío';

function format_lead_for_js($lead, $stage_map) {
    $name = trim($lead['first_name'] . ' ' . $lead['last_name']);
    $stage_id = array_search($lead['status'], $stage_map);
    
    return [
        'id' => $lead['id'],
        'name' => $name,
        'source' => $lead['source'],
        'stage' => $stage_id !== false ? $stage_id : null,
        'status_text' => $lead['status'],
        'first_name' => $lead['first_name'],
        'last_name' => $lead['last_name'],
        'email' => $lead['email'],
        'phone_fixed' => $lead['phone'],
        'phone_mobile' => $lead['mobile'],
        'company' => $lead['company'],
        'address' => $lead['street_address'],
        'city' => $lead['city'],
        'state_region' => $lead['state_province'],
        'postal_code' => $lead['zip_code'],
        'priority' => $lead['priority'],
        'lost_reason' => $lead['lost_reason']
    ];
}

function fetchFunnelProspects($pdo, $funnel_stages) {
    $stage_map = array_column($funnel_stages, 'db_status');
    $placeholders = implode(',', array_fill(0, count($stage_map), '?'));
    
    $stmt = $pdo->prepare("SELECT * FROM leads WHERE status IN ($placeholders)");
    $stmt->execute($stage_map);
    $leads = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    $formatted_leads = [];
    $stage_db_to_id_map = array_column($funnel_stages, 'id', 'db_status');
    
    foreach ($leads as $lead) {
        $js_lead = format_lead_for_js($lead, $stage_db_to_id_map);
        $js_lead['stage'] = $stage_db_to_id_map[$lead['status']];
        $formatted_leads[] = $js_lead;
    }
    return $formatted_leads;
}

function fetchConvertedProspects($pdo, $converted_status) {
    $stmt = $pdo->prepare("SELECT * FROM leads WHERE status = ?");
    $stmt->execute([$converted_status]);
    $leads = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    $formatted_leads = [];
    foreach ($leads as $lead) {
        $formatted_leads[] = format_lead_for_js($lead, []);
    }
    return $formatted_leads;
}

function fetchLostProspects($pdo, $lost_status) {
    $stmt = $pdo->prepare("SELECT * FROM leads WHERE status = ?");
    $stmt->execute([$lost_status]);
    $leads = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    $formatted_leads = [];
    foreach ($leads as $lead) {
        $js_lead = format_lead_for_js($lead, []);
        $js_lead['source'] = $lead['lost_reason'] ? $lead['lost_reason'] : 'Razón no especificada';
        $formatted_leads[] = $js_lead;
    }
    return $formatted_leads;
}

// --- EJECUCIÓN DE LÓGICA DE DATOS ---
$funnel_prospects = fetchFunnelProspects($pdo, $funnel_stages);
$converted_prospects = fetchConvertedProspects($pdo, $converted_db_status);
$lost_prospects = fetchLostProspects($pdo, $lost_db_status);

// --- LÓGICA DE DATOS ADICIONAL ---
$total_new_prospects = count($funnel_prospects);
$total_converted = count($converted_prospects);
$total_lost = count($lost_prospects);
$total_decided = $total_converted + $total_lost;
$conversion_rate = ($total_decided > 0) ? round(($total_converted / $total_decided) * 100, 1) : 0;

try {
    $sources_stmt = $pdo->query("SELECT name FROM lead_sources ORDER BY name ASC");
    $lead_sources = $sources_stmt->fetchAll(PDO::FETCH_COLUMN);
} catch (PDOException $e) {
    $lead_sources = ['Fuente No Disponilbe'];
}
$priority_levels = ['Alta', 'Media', 'Baja'];

$funnel_stages_js = array_values($funnel_stages);
?>
<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>FlowCRM™ Tu Centro De Control Empresarial Powered By OrozCO</title>
  <meta name="description" content="La Plataforma Todo En Uno Para Impulsar Tu Negocio">
  <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>
    <link rel="stylesheet" href="style.css"> 
    <script src="files/header-manager.js"></script>
    <script src="https://unpkg.com/imask"></script>     
</head>

<body data-page-title="Embudo De Conversión De Prospectos" 
    data-page-subtitle="Convirtiendo Desconocidos En Clientes Potenciales" 
    data-page-icon="shuffle">
    
    <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 bg-[var(--color-background)] space-y-8">
            
<div>
            <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">

                <div class="bg-white p-6 rounded-xl shadow-md flex items-center space-x-4 border-l-4 border-[var(--color-primary)]">
                    <i data-lucide="users" class="w-12 h-12 text-gray-700"></i>
                    <div>
                        <h3 class="text-lg font-extrabold text-gray-500 mb-1 uppercase">LEADS EN SEGUIMIENTO</h3>
                        <p id="kpi-new-prospects" class="text-5xl font-bold text-[var(--color-primary)]"><?php echo $total_new_prospects; ?></p>
                    </div>
                </div>

                <div class="bg-white p-6 rounded-xl shadow-md flex items-center space-x-4 border-l-4 border-emerald-500">
                    <i data-lucide="user-check" class="w-12 h-12 text-gray-700"></i>
                    <div>
                        <h3 class="text-lg font-extrabold text-gray-500 mb-1 uppercase">SOLICITARON COTIZACIÓN</h3>
                        <p id="kpi-converted" class="text-5xl font-bold text-[var(--color-primary)]"><?php echo $total_converted; ?></p>
                    </div>
                </div>

                <div class="bg-white p-6 rounded-xl shadow-md flex items-center space-x-4 border-l-4 border-[var(--color-secondary)]">
                    <i data-lucide="percent-circle" class="w-12 h-12 text-gray-700"></i>
                    <div>
                        <h3 class="text-lg font-extrabold text-gray-500 mb-1 uppercase">TASA DE CONVERSIÓN</h3>
                        <p id="kpi-rate" class="text-5xl font-bold text-[var(--color-primary)]"><?php echo $conversion_rate; ?>%</p>
                    </div>
                </div>

            </div>
        </div>
            
            <div>
                <div class="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-3 gap-6">
                    <?php foreach ($funnel_stages as $stage): ?>
                    <div>
                                                <div id="stage-<?php echo $stage['id']; ?>" data-stage-id="<?php echo $stage['id']; ?>" class="funnel-column bg-white rounded-xl p-4 flex flex-col min-h-[65vh] transition duration-300 transform uppercase shadow-lg hover:shadow-xl <?php echo $stage['border_class']; ?>">
                            <div class="flex-shrink-0">
                                <div class="flex justify-between items-center mb-2 border-b pb-2">
                                    <h2 class="text-2xl font-black flex items-center <?php echo $stage['color_class']; ?>"><i data-lucide="<?php echo $stage['icon']; ?>" class="w-5 h-5 mr-2"></i><?php echo htmlspecialchars($stage['title']); ?></h2>
                                    <span class="text-gray-500 font-bold" id="count-<?php echo $stage['id']; ?>"></span>
                                </div>
                                <p class="text-md font-semibold text-gray-600 mb-4 h-10"><?php echo htmlspecialchars($stage['desc']); ?></p><br />
                            </div>
                             <div class="kanban-list space-y-4 flex-grow overflow-y-auto pr-2" data-stage-id="<?php echo $stage['id']; ?>"></div>
                        </div>
                    </div>
                    <?php endforeach; ?>
                </div>

                <div class="mt-8">
                     <h3 class="text-4xl font-black text-[var(--color-primary)] mb-3 flex items-center">
                         <i data-lucide="check-square" class="w-7 h-7 mr-2"></i>RESULTADOS DEL EMBUDO</h3>
                     <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                        <div>
                             <div id="converted-column" data-action="convert" class="funnel-column bg-white rounded-xl p-4 flex flex-col min-h-[40vh] transition duration-300 shadow-lg hover:shadow-xl border-l-4 border-emerald-500">
                                <div class="flex-shrink-0">
                                    <div class="flex justify-between items-center mb-2 border-b pb-2">
                                        <h2 class="text-3xl font-black flex items-center uppercase text-emerald-600"><i data-lucide="user-check" class="w-5 h-5 mr-2"></i><?php echo strtoupper($converted_db_status); ?></h2>
                                        <span class="text-gray-500 font-bold" id="count-converted"></span>
                                    </div>
                                    <p class="text-md text-gray-500 mb-3 h-8">Interesados Que Solicitaron Una Cotización Para Un Proyecto</p>
                                </div>
                                <div id="converted-list" class="kanban-list space-y-3 flex-grow overflow-y-auto pr-2"></div>
                            </div>
                         </div>
                        <div>
                             <div id="lost-column" data-action="lost" class="funnel-column bg-white rounded-xl p-4 flex flex-col min-h-[40vh] transition duration-300 shadow-lg hover:shadow-xl border-l-4 border-[var(--color-secondary)]">
                                <div class="flex-shrink-0">
                                    <div class="flex justify-between items-center mb-2 border-b pb-2">
                                        <h2 class="text-3xl font-black flex items-center text-[var(--color-secondary)]"><i data-lucide="user-x" class="w-5 h-5 mr-2"></i><?php echo strtoupper($lost_db_status); ?></h2>
                                        <span class="text-gray-500 font-bold" id="count-lost"></span>
                                    </div>
                                     <p class="text-md text-gray-500 mb-3 h-8">Interesados Que No Continuaron En El Proceso Por Alguna Razón</p>
                                </div>
                                <div id="lost-list" class="kanban-list space-y-3 flex-grow overflow-y-auto pr-2"></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </main>
</div>

<div id="notes-panel-overlay" class="fixed inset-0 bg-black bg-opacity-50 z-40 transition-opacity duration-300 opacity-0 pointer-events-none" onclick="closeNotesPanel()"></div>
<aside id="notes-panel" 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 flex flex-col shadow-2xl">
    <div class="p-4 bg-[var(--color-primary)] border-b border-gray-200 flex-shrink-0 flex justify-between items-center ">
        <h3 class="text-3xl font-black text-[var(--color-highlight)] flex items-center"> <i data-lucide="user-plus" class="w-5 h-5 mr-2 text-[var(--color-highlight)]"></i> DATOS DEL INTERESADO </h3> <button class="text-gray-400 hover:text-[var(--color-secondary)] p-1 rounded-full transition-colors duration-200" onclick="closeNotesPanel()"> <i data-lucide="x" class="w-6 h-6"></i> </button> </div>
    <div class="p-4 overflow-y-auto flex-grow space-y-6">
        <div id="prospect-info-card" class="bg-white p-4 rounded-xl shadow-lg border-l-4 border-[var(--color-secondary)] transition duration-300">
             <div class="border-b pb-3 mb-4"> <div class="flex justify-between items-start mb-1"> <h4 class="text-lg font-black text-[var(--color-secondary)] flex items-center"> <i data-lucide="user" class="w-5 h-5 mr-2"></i> <span id="panel-prospect-name" class="break-words"></span> </h4> <span class="text-xs font-semibold bg-gray-200 text-gray-700 px-2 py-0.5 rounded-full" id="panel-prospect-stage"></span> </div> <p class="text-sm text-gray-500 font-semibold flex items-center"> <i data-lucide="compass" class="w-4 h-4 mr-1.5 text-gray-500"></i>Fuente: <span id="panel-prospect-source" class="ml-1 font-medium text-gray-700"></span> </p> <p class="text-xs font-light text-gray-400 mt-1 text-right">ID: <span id="panel-prospect-id"></span></p> </div>
            <div class="space-y-4">
                <div class="grid grid-cols-2 gap-4"> <div> <label for="panel-prospect-first-name" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Primer Nombre</label> <input type="text" id="panel-prospect-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" placeholder="Nombre"> </div> <div> <label for="panel-prospect-last-name" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Apellido</label> <input type="text" id="panel-prospect-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" placeholder="Apellido"> </div> </div>
                 <div> <label for="panel-prospect-company" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Empresa (Opcional)</label>
                 <input type="text" id="panel-prospect-company" 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="Nombre del Negocio">
                </div>
                 <label for="panel-prospect-status-select" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Estado del Prospecto</label>
                 <select id="panel-prospect-status-select" 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 bg-white">
                    </select>
                <div class="border-t pt-4"> <div> <label for="panel-prospect-email" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Email</label> <input type="email" id="panel-prospect-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" placeholder="ejemplo@cliente.com"> </div> <div class="grid grid-cols-2 gap-4 mt-4"> <div> <label for="panel-prospect-phone-fixed" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Teléfono Fijo</label> <input type="tel" id="panel-prospect-phone-fixed" 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="(XXX) XXX-XXXX"> </div> <div> <label for="panel-prospect-phone-mobile" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Celular</label> <input type="tel" id="panel-prospect-phone-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" placeholder="(XXX) XXX-XXXX"> </div> </div> </div>
                 <div class="border-t pt-4"> <div> <label for="panel-prospect-address" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Dirección (Calle y Número)</label> <input type="text" id="panel-prospect-address" 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="Ej. 123 Main St"> </div> <div class="grid grid-cols-3 gap-4 mt-4"> <div> <label for="panel-prospect-city" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Ciudad</label> <input type="text" id="panel-prospect-city" 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="Ej. Springfield"> </div> <div> <label for="panel-prospect-state-region" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Estado</label> <input type="text" id="panel-prospect-state-region" 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="Ej. IL"> </div> <div> <label for="panel-prospect-postal-code" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Cód. Postal</label> <input type="text" id="panel-prospect-postal-code" 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="Ej. 62704"> </div> </div> </div>
                 <div class="border-t pt-4"> <div class="grid grid-cols-2 gap-4"> <div> <label for="panel-prospect-source-select" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Fuente</label> <select id="panel-prospect-source-select" 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 bg-white"> <option value="">Seleccionar...</option> <?php foreach ($lead_sources as $source): ?> <option value="<?php echo htmlspecialchars($source); ?>"><?php echo htmlspecialchars($source); ?></option> <?php endforeach; ?> </select> </div> <div> <label for="panel-prospect-priority" class="block text-xs font-semibold text-gray-600 mb-1 uppercase">Prioridad</label> <select id="panel-prospect-priority" 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 bg-white"> <?php foreach ($priority_levels as $level): ?> <option value="<?php echo htmlspecialchars($level); ?>"><?php echo htmlspecialchars(strtoupper($level)); ?></option> <?php endforeach; ?> </select> </div> </div> </div>
            </div>
        </div>
        <div class="bg-white p-4 rounded-xl shadow-lg transition duration-300"> <h4 class="text-lg font-bold text-[var(--color-primary)] mb-3 flex items-center border-b pb-1"> <i data-lucide="message-square-plus" class="w-5 h-5 mr-2 text-[var(--color-primary)]"></i> NUEVA NOTA DE SEGUIMIENTO </h4> <textarea id="new-note-content" class="w-full p-2 border border-gray-300 rounded-lg focus:border-[var(--color-secondary)] focus:ring-[var(--color-secondary)] focus:ring-1 transition duration-150 text-sm mb-3" rows="3" placeholder="Escriba aquí el resumen de la interacción, dudas del cliente, o el siguiente paso..."></textarea> <h4 class="text-lg font-bold text-[var(--color-primary)] mb-3 flex items-center border-b pb-1"> <i data-lucide="history" class="w-5 h-5 mr-2 text-[var(--color-primary)]"></i> HISTORIAL DE SEGUIMIENTO </h4> <div id="notes-list" class="space-y-3 max-h-60 overflow-y-auto pr-2"> </div> </div>
    </div>
    <div class="p-4 bg-gray-100 border-t border-gray-200 flex-shrink-0"> <button id="save-tracking-btn" class="w-full bg-[var(--color-secondary)] text-white font-black py-2.5 uppercase px-4 rounded-lg shadow-md hover:shadow-lg hover:-translate-y-0.5 transition-all duration-300 ease-in-out hover:bg-[var(--color-secondary)]"> <i data-lucide="save" class="w-5 h-5 mr-2 inline-block"></i> Actualizar Información </button> </div>
</aside>

<div id="promptLostReasonModal" class="fixed inset-0 bg-gray-900 bg-opacity-75 flex items-center justify-center hidden z-50">
    <div class="bg-white p-8 rounded-xl shadow-2xl w-full max-w-sm m-4 transform transition-all duration-300 scale-95 opacity-0 text-center">
        <div class="flex justify-center mb-4">
            <i data-lucide="help-circle" class="w-16 h-16 text-[var(--color-secondary)]"></i>
        </div>
        <h3 class="text-2xl font-bold text-[var(--color-primary)] mb-4 uppercase">¿POR QUÉ SE DESCARTÓ?</h3>
        <p class="text-gray-700 mb-6">Por favor, ingrese la razón principal por la que este prospecto no continuó en el proceso:</p>
        
        <input type="text" id="lost-reason-input" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-[var(--color-secondary)] focus:border-[var(--color-secondary)] text-sm mb-6" placeholder="Ej: Precio elevado, No responde, Ya tiene proveedor" required>

        <div class="flex justify-center space-x-4">
            <button 
                type="button" 
                class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase" 
                onclick="closeModal('promptLostReasonModal')">
                CANCELAR
            </button>
            <button 
                type="button" 
                class="btn-secondary font-bold py-2 px-4 rounded-lg uppercase" 
                id="confirm-lost-reason-btn">
                CONFIRMAR DESCARTE
            </button>
        </div>
    </div>
</div>

<div id="confirmMoveToQuoteModal" class="fixed inset-0 bg-gray-900 bg-opacity-75 flex items-center justify-center hidden z-50">
    <div class="bg-white p-8 rounded-xl shadow-2xl w-full max-w-sm m-4 transform transition-all duration-300 scale-95 opacity-0 text-center">
        <div class="flex justify-center mb-4">
            <i data-lucide="send" class="w-16 h-16 text-emerald-600"></i>
        </div>
        <h3 class="text-2xl font-black text-emerald-600 mb-4 uppercase">MOVER AL SEGUIMIENTO DE COTIZACIÓN</h3>
        <p class="text-gray-700 mb-6 uppercase">
            ¿Confirmas mover el lead 
            <span id="move-quote-lead-name" class="font-semibold text-emerald-600"></span> al siguiente embudo?
            Su Estado Será Cambiado A "COTIZACIÓN ENVIADA".
        </p>
        <div class="flex justify-center space-x-4">
            <button 
                type="button" 
                class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase" 
                onclick="closeModal('confirmMoveToQuoteModal')">
                CANCELAR
            </button>
            <button 
                type="button" 
                class="btn-primary font-bold py-2 px-4 rounded-lg uppercase" 
                id="confirm-move-to-quote-btn">
                CONFIRMAR
            </button>
        </div>
    </div>
</div>

<div id="confirmArchiveModal" class="fixed inset-0 bg-gray-900 bg-opacity-75 flex items-center justify-center hidden z-50">
    <div class="bg-white p-8 rounded-xl shadow-2xl w-full max-w-sm m-4 transform transition-all duration-300 scale-95 opacity-0 text-center">
        <div class="flex justify-center mb-4">
            <i data-lucide="archive" class="w-16 h-16 text-[var(--color-secondary)]"></i>
        </div>
        <h3 class="text-2xl font-bold text-[var(--color-secondary)] mb-4 uppercase">ARCHIVAR DEFINITIVAMENTE</h3>
        <p class="text-gray-700 mb-6 uppercase">
            ¿Confirmas archivar a 
            <span id="archive-lead-name" class="font-semibold text-[var(--color-secondary)]"></span>? 
            Se moverá al centro de Leads Descartados.
        </p>
        <div class="flex justify-center space-x-4">
            <button 
                type="button" 
                class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-4 rounded-lg uppercase" 
                onclick="closeModal('confirmArchiveModal')">
                CANCELAR
            </button>
            <button 
                type="button" 
                class="btn-secondary font-bold py-2 px-4 rounded-lg uppercase" 
                id="confirm-archive-btn">
                ARCHIVAR
            </button>
        </div>
    </div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
    // --- DATOS INICIALES (Desde PHP) ---
    let funnelData = <?php echo json_encode($funnel_prospects); ?>;
    let convertedData = <?php echo json_encode($converted_prospects); ?>;
    let lostData = <?php echo json_encode($lost_prospects); ?>;
    const stagesData = <?php echo json_encode($funnel_stages_js); ?>;
    const leadSources = <?php echo json_encode($lead_sources); ?>;
    const priorityLevels = <?php echo json_encode($priority_levels); ?>;

    // Estados finales definidos en PHP
    const convertedDbStatus = '<?php echo $converted_db_status; ?>';
    const lostDbStatus = '<?php echo $lost_db_status; ?>';
    const quoteFunnelStatus = '<?php echo $quote_funnel_status; ?>'; // Asegúrate que esta variable PHP exista y tenga el valor correcto (ej: 'Cotización Enviada')

    // --- VARIABLES GLOBALES ---
    let draggedItem = null; // Elemento que se está arrastrando
    let currentProspectId = null; // ID del prospecto abierto en el panel lateral
    let draggedProspectIdToLose = null; // ID guardado al soltar en 'lost' para el modal
    let leadIdToMoveOrArchive = null; // ID guardado para botones de resultado (mover a cotización, archivar)
    window.tempProspectDataForUpdate = null; // Datos temporales para guardar desde modal 'lost'

    // --- REFERENCIAS A ELEMENTOS DEL DOM ---
    const notesPanel = document.getElementById('notes-panel');
    const notesOverlay = document.getElementById('notes-panel-overlay');
    // ... (otras referencias si las necesitas globalmente) ...

    // =================================================================
    // FUNCIONES DE UTILIDAD (Toast, Modales, Máscaras, Iconos)
    // =================================================================

    /** Muestra un mensaje temporal (toast) */
    function showToast(message, type = 'info') {
        const toastContainer = document.getElementById('toast-container');
        if (!toastContainer) return;
        const toast = document.createElement('div');
        toast.className = `toast toast-${type}`;
        let icon = 'info';
        if (type === 'success') icon = 'check-circle';
        if (type === 'error') icon = 'alert-circle';
        if (type === 'warning') icon = 'alert-triangle';
        toast.innerHTML = `<i data-lucide="${icon}" class="w-5 h-5"></i><span>${message}</span>`;
        toastContainer.appendChild(toast);
        lucide.createIcons({ container: toast });
        setTimeout(() => toast.classList.add('show'), 100);
        setTimeout(() => {
            toast.classList.remove('show');
            setTimeout(() => { if (toastContainer.contains(toast)) toastContainer.removeChild(toast); }, 500);
        }, 4000);
    }

    /** Abre un modal */
    function openModal(modalId) {
        const modal = document.getElementById(modalId);
        if (!modal) 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'; // Bloquear scroll
        lucide.createIcons(); // Recrear iconos por si acaso
    }

    /** Cierra un modal (Hecha global para onclick) */
    window.closeModal = function(modalId) {
        const modal = document.getElementById(modalId);
        if (!modal) 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 = ''; // Desbloquear scroll
            // Limpia input de razón al cerrar su modal específico
            if (modalId === 'promptLostReasonModal') {
                 document.getElementById('lost-reason-input').value = '';
            }
        }, 300);
    }

    /** Cierra el panel lateral de notas/detalles */
    window.closeNotesPanel = function() {
        if (!notesPanel || !notesOverlay) return;
        notesPanel.classList.add('translate-x-full');
        notesOverlay.classList.remove('opacity-100');
        notesOverlay.classList.add('opacity-0', 'pointer-events-none');
        currentProspectId = null; // Limpia el ID actual
        document.getElementById('new-note-content').value = ''; // Limpia campo nueva nota
    }

    /** Aplica máscaras de formato a los campos de teléfono en el panel lateral */
    function applyPhoneMasksToPanel() {
        const phoneFixedInput = document.getElementById('panel-prospect-phone-fixed');
        const phoneMobileInput = document.getElementById('panel-prospect-phone-mobile');
        if (typeof IMask !== 'undefined') {
            try {
                if (phoneFixedInput && !phoneFixedInput.imask) {
                    phoneFixedInput.imask = IMask(phoneFixedInput, { mask: '(000) 000-0000', lazy: false });
                }
                if (phoneMobileInput && !phoneMobileInput.imask) {
                    phoneMobileInput.imask = IMask(phoneMobileInput, { mask: '(000) 000-0000', lazy: false });
                }
            } catch (error) { console.error("Error al aplicar iMask:", error); }
        } else { console.warn("IMask no está definido."); }
    }

    // =================================================================
    // LÓGICA DEL PANEL LATERAL (ABRIR, CARGAR NOTAS, GUARDAR)
    // =================================================================

    /** Abre el panel lateral, carga datos y notas del prospecto */
    window.openNotesPanel = async function(prospectId) {
        const prospect = [...funnelData, ...convertedData, ...lostData].find(p => p.id == prospectId);
        if (!prospect) {
            console.error("Prospecto no encontrado ID:", prospectId);
            showToast(`Error: Prospecto ID ${prospectId} no encontrado.`, 'error'); return;
        }
        currentProspectId = prospectId;

        // Llenar cabecera del panel
        document.getElementById('panel-prospect-name').textContent = prospect.name || 'N/A';
        document.getElementById('panel-prospect-source').textContent = prospect.source || 'N/A';
        document.getElementById('panel-prospect-id').textContent = prospect.id;

        // Mapear status_text a título amigable para mostrar
        const stageInfo = stagesData.find(s => s.db_status === prospect.status_text);
        let statusDisplay = prospect.status_text.toUpperCase();
        if (stageInfo) { statusDisplay = stageInfo.title; }
        else if (prospect.status_text === convertedDbStatus) { statusDisplay = 'COTIZACION SOLICITADA'; }
        else if (prospect.status_text === lostDbStatus) { statusDisplay = 'DESCARTADO'; }
        document.getElementById('panel-prospect-stage').textContent = statusDisplay;

        // Llenar campos del formulario
        document.getElementById('panel-prospect-first-name').value = prospect.first_name || '';
        document.getElementById('panel-prospect-last-name').value = prospect.last_name || '';
        document.getElementById('panel-prospect-company').value = prospect.company || '';
        document.getElementById('panel-prospect-email').value = prospect.email || '';
        document.getElementById('panel-prospect-phone-fixed').value = prospect.phone_fixed || '';
        document.getElementById('panel-prospect-phone-mobile').value = prospect.phone_mobile || '';
        document.getElementById('panel-prospect-address').value = prospect.address || '';
        document.getElementById('panel-prospect-city').value = prospect.city || '';
        document.getElementById('panel-prospect-state-region').value = prospect.state_region || '';
        document.getElementById('panel-prospect-postal-code').value = prospect.postal_code || '';
        document.getElementById('panel-prospect-source-select').value = prospect.source || '';
        document.getElementById('panel-prospect-priority').value = prospect.priority || 'Media';

        // Llenar y seleccionar dropdown de ESTADO
        const statusSelect = document.getElementById('panel-prospect-status-select');
        statusSelect.innerHTML = ''; // Limpiar
        stagesData.forEach(stage => { // Fases activas
            const option = document.createElement('option');
            option.value = stage.db_status; option.textContent = stage.title; statusSelect.appendChild(option);
        });
        const convertedOpt = document.createElement('option'); // Convertido
        convertedOpt.value = convertedDbStatus; convertedOpt.textContent = 'COTIZACION SOLICITADA'; statusSelect.appendChild(convertedOpt);
        const lostOpt = document.createElement('option'); // Descartado
        lostOpt.value = lostDbStatus; lostOpt.textContent = 'DESCARTADO'; statusSelect.appendChild(lostOpt);
        statusSelect.value = prospect.status_text; // Seleccionar actual

        document.getElementById('new-note-content').value = ''; // Limpiar campo nueva nota
        await renderNotes(prospectId); // Cargar notas

        // Mostrar panel
        notesPanel.classList.remove('translate-x-full');
        notesOverlay.classList.remove('opacity-0', 'pointer-events-none');
        notesOverlay.classList.add('opacity-100');
        applyPhoneMasksToPanel(); // Aplicar máscaras
        lucide.createIcons(); // Recrear iconos
    }

    /** Carga y muestra las notas de un prospecto */
    async function renderNotes(leadId) {
        const notesList = document.getElementById('notes-list');
        notesList.innerHTML = '<p class="text-gray-500 italic text-sm p-3">Cargando notas...</p>';
        try {
            const response = await fetch(`db/leads-get-notes.php?lead_id=${leadId}`);
            const data = await response.json();
            notesList.innerHTML = ''; // Limpiar 'Cargando...'
            if (data.success && data.notes.length > 0) {
                data.notes.forEach(note => {
                    const noteDiv = document.createElement('div');
                    noteDiv.className = 'bg-white p-2 rounded-lg shadow border-l-4 border-l-[var(--color-primary)] text-sm';
                    noteDiv.innerHTML = `<div class="flex justify-between items-center text-xs mb-1 text-gray-500 font-medium"><span>${new Date(note.created_at).toLocaleString('es-ES')}</span><i data-lucide="tag" class="w-3 h-3 text-[var(--color-highlight)]"></i></div><p class="text-gray-700">${note.content}</p>`;
                    notesList.appendChild(noteDiv);
                });
            } else {
                notesList.innerHTML = '<p class="text-gray-500 italic text-sm p-3 bg-gray-50 rounded-lg">No hay notas registradas.</p>';
            }
        } catch (error) {
            console.error("Error cargando notas:", error);
            notesList.innerHTML = '<p class="text-[var(--color-secondary)] italic text-sm p-3">Error al cargar notas.</p>';
        }
        lucide.createIcons(); // Recrear iconos en las notas
    }

    /** Guarda cambios del panel (info + nota), maneja lógica de razón de pérdida */
    document.getElementById('save-tracking-btn').addEventListener('click', async () => {
        if (!currentProspectId) return;
        showToast('Guardando...', 'info');
        const prospect = [...funnelData, ...convertedData, ...lostData].find(p => p.id == currentProspectId);
        if (!prospect) { showToast('Error: Prospecto no encontrado.', 'error'); return; }

        // 1. Guardar nota si hay
        const newNoteContent = document.getElementById('new-note-content').value.trim();
        let noteSaved = !newNoteContent; // True si no hay nota que guardar
        if (newNoteContent) {
            try {
                const noteRes = await fetch('db/leads-add-note.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ lead_id: currentProspectId, content: newNoteContent }) });
                const noteResult = await noteRes.json();
                if (noteResult.success) {
                    showToast('Nota guardada.', 'success'); document.getElementById('new-note-content').value = ''; await renderNotes(currentProspectId); noteSaved = true;
                } else { showToast(noteResult.message || 'Error al guardar nota.', 'error'); noteSaved = false; }
            } catch (err) { console.error("Error fetch nota:", err); showToast('Error conexión al guardar nota.', 'error'); noteSaved = false; }
        }

        // 2. Preparar datos actualizados del prospecto
        const updatedData = {
            id: currentProspectId,
            first_name: document.getElementById('panel-prospect-first-name').value.trim(),
            last_name: document.getElementById('panel-prospect-last-name').value.trim(),
            company: document.getElementById('panel-prospect-company').value.trim(),
            email: document.getElementById('panel-prospect-email').value.trim(),
            phone: document.getElementById('panel-prospect-phone-fixed').value.trim().replace(/\D/g, ''),
            mobile: document.getElementById('panel-prospect-phone-mobile').value.trim().replace(/\D/g, ''),
            street_address: document.getElementById('panel-prospect-address').value.trim(),
            city: document.getElementById('panel-prospect-city').value.trim(),
            state_province: document.getElementById('panel-prospect-state-region').value.trim(),
            zip_code: document.getElementById('panel-prospect-postal-code').value.trim(),
            source: document.getElementById('panel-prospect-source-select').value,
            priority: document.getElementById('panel-prospect-priority').value,
            status: document.getElementById('panel-prospect-status-select').value // Nuevo estado
        };

        // 3. Lógica razón de pérdida
        let lostReason = prospect.lost_reason; // Mantener razón actual por defecto
        let requiresModal = false;
        if (updatedData.status === lostDbStatus && prospect.status_text !== lostDbStatus) { requiresModal = true; } // Cambiando A Descartado
        else if (updatedData.status !== lostDbStatus && prospect.status_text === lostDbStatus) { lostReason = null; } // Cambiando DESDE Descartado

        // 4. Ejecutar guardado (con o sin modal)
        if (requiresModal) {
            window.tempProspectDataForUpdate = updatedData; // Guardar datos para usar en modal
            document.getElementById('lost-reason-input').value = ''; // Limpiar input modal
            openModal('promptLostReasonModal');
            document.getElementById('confirm-lost-reason-btn').onclick = handleConfirmLostReasonAndUpdate; // Asignar handler
        } else {
            await executeProspectUpdate(updatedData, lostReason); // Guardar directamente
        }
    });

    /** Se llama al confirmar razón en modal (desde panel lateral) */
    async function handleConfirmLostReasonAndUpdate() {
        const lostReasonInput = document.getElementById('lost-reason-input');
        const reason = lostReasonInput.value.trim();
        if (!reason) { showToast('Debe ingresar una razón.', 'warning'); lostReasonInput.focus(); return; }
        closeModal('promptLostReasonModal');
        const dataToUpdate = window.tempProspectDataForUpdate; // Recuperar datos
        if (!dataToUpdate) { showToast('Error interno: Datos temporales no encontrados.', 'error'); return; }
        await executeProspectUpdate(dataToUpdate, reason); // Guardar con la razón
        window.tempProspectDataForUpdate = null; // Limpiar
    }

    /** Envía actualización al servidor, actualiza datos locales y re-renderiza */
    async function executeProspectUpdate(prospectData, reason) {
         try {
            const response = await fetch('db/leads-update.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...prospectData, lost_reason: reason }) });
            const result = await response.json();
            if (result.success) {
                showToast('Información actualizada.', 'success');
                // --- Actualizar datos locales ---
                let prospectInMemory = null; // Variable para el objeto prospecto en memoria
                // Busca el prospecto en las 3 listas y lo actualiza
                [funnelData, convertedData, lostData].forEach(arr => {
                    const index = arr.findIndex(p => p.id == prospectData.id);
                    if (index > -1 && !prospectInMemory) { // Si lo encuentra y no lo hemos actualizado ya
                        Object.assign(arr[index], { // Actualiza el objeto existente
                            first_name: prospectData.first_name, last_name: prospectData.last_name,
                            name: `${prospectData.first_name} ${prospectData.last_name}`.trim(),
                            company: prospectData.company, email: prospectData.email,
                            phone_fixed: prospectData.phone, phone_mobile: prospectData.mobile,
                            address: prospectData.street_address, city: prospectData.city,
                            state_region: prospectData.state_province, postal_code: prospectData.zip_code,
                            source: prospectData.source, priority: prospectData.priority,
                            status_text: prospectData.status, // Nuevo estado
                            lost_reason: reason, // Nueva razón
                            // Recalcula stage numérico (0,1,2 o null)
                            stage: Object.fromEntries(stagesData.map(s => [s.db_status, s.id]))[prospectData.status] ?? null
                        });
                        prospectInMemory = arr[index]; // Guarda referencia
                    }
                });

                // --- Reorganizar listas ---
                if (prospectInMemory) {
                     // Quitar de todas las listas
                     funnelData = funnelData.filter(p => p.id != prospectInMemory.id);
                     convertedData = convertedData.filter(p => p.id != prospectInMemory.id);
                     lostData = lostData.filter(p => p.id != prospectInMemory.id);
                     // Añadir a la lista correcta
                     if (prospectInMemory.stage !== null) funnelData.push(prospectInMemory);
                     else if (prospectInMemory.status_text === convertedDbStatus) convertedData.push(prospectInMemory);
                     else if (prospectInMemory.status_text === lostDbStatus) lostData.push(prospectInMemory);
                } else { console.error("No se pudo encontrar/actualizar prospecto local."); }
                // --- Fin Reorganizar ---

                closeNotesPanel(); // Cerrar panel
                renderAll(); // Re-dibujar todo
            } else { showToast(result.message || 'Error al actualizar.', 'error'); }
        } catch (error) { console.error("Error fetch executeUpdate:", error); showToast('Error conexión al guardar.', 'error'); }
    }

    // =================================================================
    // RENDERIZADO DEL EMBUDO (Funnel, Convertido, Perdido)
    // =================================================================

    /** Dibuja todas las secciones del embudo */
    function renderAll() {
        renderFunnelCards(); // Dibuja las 3 columnas principales
        renderConvertedCards(); // Dibuja la columna "Cotizacion Solicitada"
        renderLostCards(); // Dibuja la columna "Descartado"
        updateAllCounts(); // Actualiza los contadores
        lucide.createIcons(); // Recrea todos los iconos
    }

    /** Dibuja las tarjetas en las columnas del embudo principal (0, 1, 2) */
    function renderFunnelCards() {
        document.querySelectorAll('.kanban-list[data-stage-id]').forEach(list => list.innerHTML = ''); // Limpia listas
        funnelData.forEach(prospect => {
            if (prospect.stage !== null && prospect.stage >= 0 && prospect.stage < stagesData.length) {
                const stageInfo = stagesData[prospect.stage]; // Info de la fase (título, color, etc.)
                const targetList = document.querySelector(`.kanban-list[data-stage-id="${prospect.stage}"]`); // Busca la lista correcta
                if (targetList) {
                    targetList.appendChild(createProspectCard(prospect, stageInfo)); // Añade la tarjeta
                }
            } else { console.warn("Prospecto con fase inválida:", prospect); }
        });
    }

    /** Dibuja las tarjetas en la columna "Cotizacion Solicitada" */
    function renderConvertedCards() {
        const list = document.getElementById('converted-list'); list.innerHTML = '';
        convertedData.forEach(prospect => list.appendChild(createConvertedCard(prospect)));
    }

    /** Dibuja las tarjetas en la columna "Descartado" */
    function renderLostCards() {
        const list = document.getElementById('lost-list'); list.innerHTML = '';
        lostData.forEach(prospect => list.appendChild(createLostCard(prospect)));
    }

    /** Crea el HTML para una tarjeta de prospecto en el embudo principal */
    function createProspectCard(prospect, stage) {
        const card = document.createElement('div');
        card.className = `prospect-card bg-white p-3 rounded-lg shadow-md hover:shadow-lg border-l-4 ${stage.border_class} cursor-grab transition-all duration-200 ease-in-out hover:-translate-y-0.5`;
        card.dataset.prospectId = prospect.id;
        card.dataset.stageId = prospect.stage; // Guarda el índice (0, 1, 2)
        card.setAttribute('draggable', true);
        card.innerHTML = `
            <div class="flex justify-between items-start">
                <span class="font-bold text-gray-800 text-base">${prospect.name}</span>
                <i data-lucide="grip-vertical" class="w-4 h-4 text-gray-400"></i>
            </div>
            <div class="text-sm text-gray-500 mt-1 flex items-center"><i data-lucide="compass" class="w-4 h-4 mr-1.5"></i> Fuente: ${prospect.source || 'N/A'}</div>
            <div class="mt-3 text-right">
                <button onclick="window.openNotesPanel(${prospect.id})" class="inline-flex items-center text-xs font-bold text-white bg-[var(--color-secondary)] py-1 px-2.5 rounded-full shadow-sm hover:shadow-md hover:-translate-y-0.5 transition-all duration-200 ease-in-out">
                    VER DETALLES <i data-lucide="chevron-right" class="w-3 h-3 ml-1"></i>
                </button>
            </div>`;
        card.addEventListener('dragstart', handleDragStart);
        card.addEventListener('dragend', handleDragEnd);
        return card;
    }

    /** Crea el HTML para una tarjeta en la columna "Cotizacion Solicitada" */
    function createConvertedCard(prospect) {
        const card = document.createElement('div');
        card.className = 'prospect-card-result bg-white p-3 rounded-lg shadow-md border-l-4 border-emerald-500 cursor-grab';
        card.setAttribute('draggable', true); // Hacerla arrastrable
        card.dataset.prospectId = prospect.id;
        card.dataset.stageId = null; // No tiene stage activo
        card.innerHTML = `
            <div class="flex justify-between items-start">
                <span class="font-bold text-gray-800 text-base">${prospect.name}</span>
                <button onclick="openMoveToQuoteModal(${prospect.id}, '${prospect.name}')" title="Mover A Cotización Enviada" class="text-emerald-600 hover:text-emerald-800 p-1 rounded-full bg-emerald-50 hover:bg-emerald-100 transition-colors">
                    <i data-lucide="send" class="w-4 h-4"></i>
                </button>
            </div>
            <div class="text-sm text-gray-500 mt-1 flex items-center text-emerald-600"><i data-lucide="compass" class="w-4 h-4 mr-1.5"></i> ${prospect.source || 'N/A'}</div>
            <div class="mt-2 text-right">
                <button onclick="window.openNotesPanel(${prospect.id})" class="inline-flex items-center text-xs font-bold text-gray-700 py-1 px-2.5 rounded-full shadow-sm border border-gray-300 hover:bg-gray-100">
                    VER DETALLES
                </button>
            </div>`;
        card.addEventListener('dragstart', handleDragStart);
        card.addEventListener('dragend', handleDragEnd);
        return card;
    }

    /** Crea el HTML para una tarjeta en la columna "Descartado" */
    function createLostCard(prospect) {
        const card = document.createElement('div');
        card.className = 'prospect-card-result bg-white p-3 rounded-lg shadow-md border-l-4 border-[var(--color-secondary)] cursor-grab';
        card.setAttribute('draggable', true); // Hacerla arrastrable
        card.dataset.prospectId = prospect.id;
        card.dataset.stageId = null; // No tiene stage activo
        card.innerHTML = `
            <div class="flex justify-between items-start">
                <span class="font-bold text-gray-800 text-base">${prospect.name}</span>
                <button onclick="openArchiveModal(${prospect.id}, '${prospect.name}')" title="Archivar Definitivamente" class="text-[var(--color-secondary)] hover:text-red-800 p-1 rounded-full bg-red-50 hover:bg-red-100 transition-colors">
                     <i data-lucide="archive" class="w-4 h-4"></i>
                 </button>
            </div>
            <div class="text-sm font-bold text-[var(--color-secondary)] mt-2 flex items-start"><i data-lucide="info" class="w-4 h-4 mr-1.5 flex-shrink-0 mt-0.5"></i>Razón: ${prospect.lost_reason || 'Desconocida'}</div>
            <div class="mt-2 text-right">
                <button onclick="window.openNotesPanel(${prospect.id})" class="inline-flex items-center text-xs font-bold text-gray-700 py-1 px-2.5 rounded-full shadow-sm border border-gray-300 hover:bg-gray-100">
                    VER DETALLES
                </button>
            </div>`;
        card.addEventListener('dragstart', handleDragStart);
        card.addEventListener('dragend', handleDragEnd);
        return card;
    }

    /** Actualiza los contadores numéricos en las cabeceras de las columnas y KPIs */
    function updateAllCounts() {
        stagesData.forEach((stage) => { // Contadores fases activas
            const count = funnelData.filter(p => p.stage == stage.id).length;
            const el = document.getElementById(`count-${stage.id}`); if(el) el.textContent = `(${count})`;
        });
        // Contadores Convertido y Perdido
        const countConv = document.getElementById('count-converted'); if(countConv) countConv.textContent = `(${convertedData.length})`;
        const countLost = document.getElementById('count-lost'); if(countLost) countLost.textContent = `(${lostData.length})`;
        // KPIs
        const totalInFunnel = funnelData.length, totalConv = convertedData.length, totalL = lostData.length;
        const totalDecided = totalConv + totalL;
        const rate = (totalDecided > 0) ? Math.round((totalConv / totalDecided) * 100) : 0;
        const kpiFunnel = document.getElementById('kpi-new-prospects'); if(kpiFunnel) kpiFunnel.textContent = totalInFunnel;
        const kpiConv = document.getElementById('kpi-converted'); if(kpiConv) kpiConv.textContent = totalConv;
        const kpiRate = document.getElementById('kpi-rate'); if(kpiRate) kpiRate.textContent = `${rate}%`;
    }

    // =================================================================
    // LÓGICA DE DRAG & DROP
    // =================================================================

    function handleDragStart(e) { draggedItem = e.target; e.dataTransfer.setData('text/plain', e.target.dataset.prospectId); setTimeout(() => { if(draggedItem) draggedItem.classList.add('opacity-50'); }, 0); }
    function handleDragEnd(e) { if (draggedItem) draggedItem.classList.remove('opacity-50'); draggedItem = null; }
    function handleDragOver(e) { e.preventDefault(); const list = e.currentTarget; if (list.classList.contains('kanban-list')) list.classList.add('bg-gray-100'); }
    function handleDragLeave(e) { const list = e.currentTarget; if (list.classList.contains('kanban-list')) list.classList.remove('bg-gray-100'); }

    /** Maneja el soltar una tarjeta */
    async function handleDrop(e) {
        e.preventDefault();
        const list = e.currentTarget; if (!list.classList.contains('kanban-list')) return;
        list.classList.remove('bg-gray-100');
        const column = list.closest('.funnel-column');
        const pId = parseInt(e.dataTransfer.getData('text/plain'));
        draggedProspectIdToLose = pId; // Guardar ID para modal 'lost'
        let p = [...funnelData, ...convertedData, ...lostData].find(x => x.id === pId);
        if (!p || !draggedItem) { console.warn("Drop: Prospecto/Item no hallado."); renderAll(); return; }

        const action = column.dataset.action; // 'convert' o 'lost'
        const stageId = parseInt(column.dataset.stageId, 10); // 0, 1, 2 o NaN
        let newStatus = null, reason = p.lost_reason; // Mantener razón por defecto

        if (action === 'lost') { openModal('promptLostReasonModal'); return; } // Abre modal y detiene
        else if (action === 'convert') { newStatus = convertedDbStatus; reason = null; } // A Convertido
        else if (!isNaN(stageId) && stageId >= 0 && stageId < stagesData.length) { // A fase activa
            newStatus = stagesData[stageId].db_status;
            if (p.status_text === lostDbStatus || p.status_text === convertedDbStatus) reason = null; // Borra razón si se reactiva
        } else { console.warn("Drop en zona inválida."); renderAll(); return; } // Zona inválida

        if (newStatus && newStatus !== p.status_text) { updateStatusInDb(pId, newStatus, reason); } // Actualiza si cambió
        else { console.log("Mismo estado."); renderAll(); } // Re-renderizar si no cambió (para orden)
    }

    /** Actualiza estado y razón en DB (llamada por drop o modal) */
    async function updateStatusInDb(prospectId, newDbStatus, lostReason = null) {
        // Busca el prospecto local para tener el estado ANTERIOR (puede ser redundante pero seguro)
        const prospect = [...funnelData, ...convertedData, ...lostData].find(p => p.id === prospectId);
        if (!prospect) { showToast("Error interno al actualizar estado.", "error"); return; }

        try {
            const response = await fetch('db/leads-update-funnel-status.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: prospectId, status: newDbStatus, lost_reason: lostReason }) });
            const result = await response.json();
            if (result.success) {
                showToast('¡MOVIDO CON ÉXITO!', 'success');
                // --- Actualizar datos locales ---
                prospect.status_text = newDbStatus; // Actualiza estado
                prospect.lost_reason = lostReason; // Actualiza razón
                prospect.stage = Object.fromEntries(stagesData.map(s => [s.db_status, s.id]))[newDbStatus] ?? null; // Recalcula stage
                // --- Reorganizar listas ---
                funnelData = funnelData.filter(p => p.id != prospectId);
                convertedData = convertedData.filter(p => p.id != prospectId);
                lostData = lostData.filter(p => p.id != prospectId);
                if (prospect.stage !== null) funnelData.push(prospect);
                else if (prospect.status_text === convertedDbStatus) convertedData.push(prospect);
                else if (prospect.status_text === lostDbStatus) lostData.push(prospect);
                // --- Fin Reorganizar ---
                renderAll(); // Re-dibujar
            } else { showToast(result.message || 'Error al mover.', 'error'); renderAll(); } // Error PHP, revertir visual
        } catch (error) { console.error("Error fetch updateStatus:", error); showToast('Error conexión al mover.', 'error'); renderAll(); } // Error Conexión, revertir visual
    }

    /** Lógica del modal de descarte (llamada por botón del modal) */
    window.confirmLostReasonLogic = async function() {
        const reasonInput = document.getElementById('lost-reason-input');
        const reason = reasonInput.value.trim();
        const pId = draggedProspectIdToLose; // ID guardado al iniciar drop en 'lost'
        if (!reason) { showToast('Debe ingresar una razón.', 'warning'); reasonInput.focus(); return; }
        if (!pId) { showToast('Error: ID no encontrado.', 'error'); closeModal('promptLostReasonModal'); return; }
        closeModal('promptLostReasonModal');
        await updateStatusInDb(pId, lostDbStatus, reason); // Llama a actualizar con el estado 'lost' y la razón
        draggedProspectIdToLose = null; // Limpiar ID temporal
    }

    // =================================================================
    // LÓGICA DE BOTONES DE RESULTADO (MOVER A COTIZACIÓN, ARCHIVAR)
    // =================================================================

    /** Abre modal para confirmar mover a Cotización Enviada */
    window.openMoveToQuoteModal = function(leadId, leadName) { leadIdToMoveOrArchive = leadId; document.getElementById('move-quote-lead-name').textContent = leadName; openModal('confirmMoveToQuoteModal'); }
    /** Lógica para mover a Cotización Enviada (llamada por botón del modal) */
    window.confirmMoveToQuoteLogic = function() { if (!leadIdToMoveOrArchive) return; closeModal('confirmMoveToQuoteModal'); updateStatusInDb(leadIdToMoveOrArchive, quoteFunnelStatus); } // Usa quoteFunnelStatus

    /** Abre modal para confirmar archivar */
    window.openArchiveModal = function(leadId, leadName) { leadIdToMoveOrArchive = leadId; document.getElementById('archive-lead-name').textContent = leadName; openModal('confirmArchiveModal'); }
    /** Lógica para archivar (llamada por botón del modal) */
    window.confirmArchiveLogic = function() { if (!leadIdToMoveOrArchive) return; closeModal('confirmArchiveModal'); updateStatusInDb(leadIdToMoveOrArchive, lostDbStatus, 'Archivado manualmente'); } // Usa lostDbStatus y razón fija

    // =================================================================
    // INICIALIZACIÓN Y EVENT LISTENERS GENERALES
    // =================================================================

    // Asignar listeners a botones de confirmación de modales
    const confirmLostBtn = document.getElementById('confirm-lost-reason-btn'); if (confirmLostBtn) confirmLostBtn.addEventListener('click', window.confirmLostReasonLogic);
    const confirmMoveBtn = document.getElementById('confirm-move-to-quote-btn'); if (confirmMoveBtn) confirmMoveBtn.addEventListener('click', window.confirmMoveToQuoteLogic);
    const confirmArchiveBtn = document.getElementById('confirm-archive-btn'); if (confirmArchiveBtn) confirmArchiveBtn.addEventListener('click', window.confirmArchiveLogic);

    // Menú móvil
    const mobileMenuButton = document.getElementById('mobile-menu-button'); const sidebar = document.getElementById('sidebar'); const sidebarOverlay = document.getElementById('sidebar-overlay');
    if (mobileMenuButton && sidebar && sidebarOverlay) {
        mobileMenuButton.addEventListener('click', () => { sidebar.classList.toggle('-translate-x-full'); sidebarOverlay.classList.toggle('hidden'); });
        sidebarOverlay.addEventListener('click', () => { sidebar.classList.add('-translate-x-full'); sidebarOverlay.classList.add('hidden'); });
    }

    // Añadir listeners de drag-and-drop a todas las listas
    document.querySelectorAll('.kanban-list').forEach(list => {
        list.addEventListener('dragover', handleDragOver);
        list.addEventListener('dragleave', handleDragLeave);
        list.addEventListener('drop', handleDrop);
    });

    renderAll(); // Dibujar el embudo inicial
});
</script>
</body>
</html>