<?php
// ----------------------------------------------------------------------------------
// LÓGICA BACKEND (PHP)
// ----------------------------------------------------------------------------------
if (!isset($_SESSION['Acceso']) || $_SESSION['Acceso'] !== 'AccesoSiqueSi') {
    die("Acceso Denegado. Por favor inicie sesión.");
}
?>

<!-- ----------------------------------------------------------------------------------
     ESTILOS CSS (FULL SCREEN & MODULO)
     ---------------------------------------------------------------------------------- -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>

<style>
    /* Contenedor Principal */
    .gps-immersive-container {
        position: relative;
        width: 100%;
        height: 85vh;
        background: #f4f7fa;
        overflow: hidden;
        border-radius: 4px;
        box-shadow: 0 0 15px rgba(0,0,0,0.1);
    }

    #mapid {
        position: absolute;
        top: 0; bottom: 0; left: 0; right: 0;
        z-index: 1;
    }

    /* Botón Flotante */
    .floating-control-btn {
        position: absolute;
        top: 20px; left: 20px;
        z-index: 999;
        background: white;
        border: none;
        padding: 10px 15px;
        border-radius: 50px;
        box-shadow: 0 4px 10px rgba(0,0,0,0.2);
        cursor: pointer;
        transition: all 0.2s;
        font-weight: 600;
        color: #3f4d67;
        display: flex; align-items: center; gap: 8px;
    }
    .floating-control-btn:hover {
        transform: translateY(-2px);
        background: #3f4d67; color: white;
    }

    /* Sidebars */
    .map-sidebar {
        position: absolute;
        top: 0; bottom: 0;
        width: 340px; /* Un poco más ancho para el slider */
        background: rgba(255, 255, 255, 0.96);
        backdrop-filter: blur(5px);
        z-index: 1000;
        box-shadow: 0 0 20px rgba(0,0,0,0.15);
        transition: transform 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
        display: flex; flex-direction: column;
    }

    .sidebar-header {
        padding: 15px 20px;
        background: #3f4d67;
        color: white;
        display: flex; justify-content: space-between; align-items: center;
    }
    
    .sidebar-content {
        flex: 1;
        overflow-y: auto;
        padding: 20px;
    }

    .btn-close-custom {
        background: transparent; border: none; color: white; font-size: 1.2rem; cursor: pointer;
    }

    /* Sidebar Izquierdo */
    #filterSidebar { left: 0; transform: translateX(-100%); border-right: 1px solid #ddd; }
    #filterSidebar.active { transform: translateX(0); }

    /* Sidebar Derecho */
    #detailSidebar { right: 0; transform: translateX(100%); border-left: 1px solid #ddd; }
    #detailSidebar.active { transform: translateX(0); }

    /* Detalles y Badges */
    .detail-row { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #eee; }
    .detail-row label { font-weight: bold; color: #666; font-size: 0.85rem; margin: 0; }
    .status-pill { display: inline-block; padding: 5px 12px; border-radius: 15px; font-size: 0.75rem; font-weight: 700; text-transform: uppercase; }
    .status-ok { background: #e6fffa; color: #2c7a7b; border: 1px solid #b2f5ea; }
    .status-err { background: #fff5f5; color: #c53030; border: 1px solid #fed7d7; }
    .status-warn { background: #fffaf0; color: #c05621; border: 1px solid #fbd38d; }

    /* Toggle Switch */
    .toggle-switch { display: flex; align-items: center; margin-bottom: 20px; background: #f1f1f1; padding: 10px; border-radius: 8px; }
    .toggle-switch input { margin-right: 10px; transform: scale(1.2); cursor: pointer; }
    .toggle-switch label { margin: 0; cursor: pointer; font-size: 0.9rem; font-weight: 600; color: #555; }
    
    .live-indicator {
        width: 10px; height: 10px; background-color: #28a745; border-radius: 50%; display: inline-block; margin-left: auto;
        opacity: 0; transition: opacity 0.3s;
    }
    .live-indicator.active { opacity: 1; animation: pulse-green 2s infinite; }
    @keyframes pulse-green {
        0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(40, 167, 69, 0.7); }
        70% { transform: scale(1); box-shadow: 0 0 0 10px rgba(40, 167, 69, 0); }
        100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(40, 167, 69, 0); }
    }

    /* --- ESTILOS DEL SLIDER DE TIEMPO --- */
    #historyControls {
        margin-top: 20px;
        padding-top: 20px;
        border-top: 2px dashed #ddd;
        background: #fafafa;
        border-radius: 8px;
        padding: 15px;
    }
    
    .range-container {
        margin-top: 15px;
    }

    input[type=range] {
        width: 100%;
        margin: 10px 0;
        cursor: pointer;
    }

    .time-display {
        text-align: center;
        font-size: 1.2rem;
        font-weight: bold;
        color: #3f4d67;
        font-family: monospace;
        background: #fff;
        border: 1px solid #ccc;
        border-radius: 4px;
        padding: 5px;
        margin-bottom: 10px;
    }

    .playback-info {
        font-size: 0.8rem;
        color: #666;
        display: flex;
        justify-content: space-between;
    }

    /* --- ESTILOS MARCADOR DIRECCIONAL (FLECHA) --- */
    .gps-marker-wrapper {
        position: relative;
        width: 40px;
        height: 40px;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    /* Punto Central */
    .gps-core-dot {
        width: 12px;
        height: 12px;
        background-color: #007bff; /* Azul */
        border: 2px solid white;
        border-radius: 50%;
        box-shadow: 0 1px 3px rgba(0,0,0,0.5);
        z-index: 2;
    }
    /* Contenedor Giratorio */
    .gps-arrow-rotate {
        position: absolute;
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        /* La flecha estará en la parte superior del contenedor girado */
        transition: transform 0.3s linear; 
        z-index: 1;
    }
    /* La forma de la flecha */
    .gps-arrow-shape {
        width: 0; 
        height: 0; 
        border-left: 7px solid transparent;
        border-right: 7px solid transparent;
        border-bottom: 18px solid #007bff; /* Mismo azul */
        margin-top: 2px; /* Ajuste fino para que la base quede cerca del centro */
        filter: drop-shadow(0 0 2px rgba(0,0,0,0.3));
    }
</style>

<!-- ----------------------------------------------------------------------------------
     ESTRUCTURA HTML
     ---------------------------------------------------------------------------------- -->
<div class="gps-immersive-container">

    <!-- Botón Flotante -->
    <button class="floating-control-btn" onclick="toggleFilterSidebar()">
        <i class="fa fa-bars"></i> Menú / Filtros
    </button>

    <!-- Mapa -->
    <div id="mapid"></div>

    <!-- Sidebar IZQUIERDO: Filtros y Control de Historia -->
    <div id="filterSidebar" class="map-sidebar">
        <div class="sidebar-header">
            <h6 class="m-0"><i class="fa fa-cogs mr-2"></i>Control de Flota</h6>
            <button class="btn-close-custom" onclick="toggleFilterSidebar()">&times;</button>
        </div>
        <div class="sidebar-content">
            
            <!-- 1. Control de Auto-Refresh (Solo visible en modo Live) -->
            <div id="liveControls">
                <div class="toggle-switch">
                    <input type="checkbox" id="chkAutoRefresh" checked onchange="toggleAutoRefresh()">
                    <label for="chkAutoRefresh">En Vivo (Auto 10s)</label>
                    <span id="liveIndicator" class="live-indicator active" title="Actualizando..."></span>
                </div>

                <div class="form-group">
                    <label class="text-muted font-weight-bold text-uppercase" style="font-size: 0.75rem;">Dispositivo:</label>
                    <select id="selectDispositivo" class="form-control" onchange="cambiarDispositivo()">
                        <option value="TODOS">Cargando...</option>
                    </select>
                    <small id="deviceCountLabel" class="device-count">Esperando datos...</small>
                </div>

                <button class="btn btn-primary btn-block shadow-sm" onclick="recargarDatos(false)">
                    <i class="fa fa-sync-alt mr-2"></i> Actualizar Ahora
                </button>
            </div>

            <!-- 2. Control de HISTORIAL (Slider) - Oculto por defecto -->
            <div id="historyControls" style="display: none;">
                <h6 class="text-primary font-weight-bold"><i class="fa fa-history"></i> Reproducción de Ruta</h6>
                
                <div class="form-group mt-3">
                    <label>Seleccionar Fecha:</label>
                    <input type="date" id="historyDate" class="form-control" onchange="cargarHistorial()">
                </div>

                <div id="sliderContainer" style="display:none; opacity: 0.5;">
                    <div class="time-display" id="historyTimeDisplay">--:--:--</div>
                    
                    <div class="range-container">
                        <input type="range" id="timeSlider" min="0" max="100" value="0" step="1" oninput="moverSlider(this.value)">
                    </div>
                    
                    <div class="playback-info">
                        <span id="startTime">00:00</span>
                        <span id="pointCount">0 puntos</span>
                        <span id="endTime">23:59</span>
                    </div>
                </div>

                <div class="mt-3 text-center">
                    <button class="btn btn-outline-danger btn-sm" onclick="salirModoHistorial()">
                        <i class="fa fa-times"></i> Salir del Historial
                    </button>
                </div>
            </div>
            
            <hr>
            <div class="alert alert-light small border">
                <i class="fa fa-info-circle text-info"></i> 
                <span id="helpText">Seleccione un dispositivo específico para ver su historial de ruta.</span>
            </div>
        </div>
    </div>

    <!-- Sidebar DERECHO: Detalles -->
    <div id="detailSidebar" class="map-sidebar">
        <div class="sidebar-header">
            <h6 class="m-0" id="detailTitle">Detalles</h6>
            <button class="btn-close-custom" onclick="cerrarDetailSidebar()">&times;</button>
        </div>
        <div class="sidebar-content" id="detailContent">
            <!-- Se llena dinámicamente -->
        </div>
    </div>

</div>

<!-- ----------------------------------------------------------------------------------
     LÓGICA JAVASCRIPT
     ---------------------------------------------------------------------------------- -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>

<script>
    // --- Variables Globales ---
    var map;
    var markersLayer;      // Capa para marcadores "En Vivo"
    var historyLayer;      // Capa para ruta y marcador de historial
    
    var allDevicesData = []; // Cache de datos "En Vivo"
    var historyData = [];    // Cache de datos de ruta histórica
    
    var refreshInterval = null;
    const DB_NAME = 'MS_GPS';
    const REFRESH_RATE_MS = 10000;
    
    var historyMarker = null; // Marcador móvil del slider
    var historyPolyline = null; // Línea de la ruta

    // --- Inicialización ---
    document.addEventListener('DOMContentLoaded', initModule);

    if (document.readyState === "complete" || document.readyState === "interactive") {
        setTimeout(initModule, 200);
    }

    function initModule() {
        if(map) return;
        
        initMap();
        
        // Poner fecha de hoy en el input date
        document.getElementById('historyDate').valueAsDate = new Date();

        cargarDatosCompletos(false);
        
        if(document.getElementById('chkAutoRefresh').checked) {
            startAutoRefresh();
        }

        setTimeout(() => { document.getElementById('filterSidebar').classList.add('active'); }, 800);
    }

    function initMap() {
        map = L.map('mapid', { zoomControl: false }).setView([19.4326, -99.1332], 5);
        L.control.zoom({ position: 'bottomright' }).addTo(map);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; OpenStreetMap'
        }).addTo(map);
        
        markersLayer = L.layerGroup().addTo(map);
        historyLayer = L.layerGroup().addTo(map);
    }

    // --- FUNCIÓN HELPER PARA ICONO CON FLECHA ---
    function createDirectionalIcon(rumbo) {
        // Asegurar que rumbo sea un número
        const deg = parseFloat(rumbo) || 0;
        
        return L.divIcon({
            className: 'custom-gps-icon', // Clase base vacía para no interferir
            html: `
                <div class="gps-marker-wrapper">
                    <div class="gps-arrow-rotate" style="transform: rotate(${deg}deg);">
                        <div class="gps-arrow-shape"></div>
                    </div>
                    <div class="gps-core-dot"></div>
                </div>
            `,
            iconSize: [40, 40], // Tamaño total del wrapper
            iconAnchor: [20, 20], // El centro exacto (mitad de 40)
            tooltipAnchor: [0, -20] // Tooltip arriba del todo
        });
    }

    // --- API AJAX ---
    async function fetchData(sql) {
        const formData = new FormData();
        formData.append('sql', sql);
        formData.append('db', DB_NAME);

        try {
            const response = await fetch('../librerias/AJAX/Select.php', { method: 'POST', body: formData });
            return await response.json();
        } catch (error) {
            console.error(error);
            return { status: false };
        }
    }

    // --- LÓGICA EN VIVO (LIVE) ---

    // Cambió el select de dispositivo
    function cambiarDispositivo() {
        // Al cambiar manualmente, queremos centrar el mapa (true)
        filtrarMapa(true);
        
        // Ajustar UI
        const imei = document.getElementById('selectDispositivo').value;
        const historyControls = document.getElementById('historyControls');
        const helpText = document.getElementById('helpText');

        if (imei === 'TODOS') {
            historyControls.style.display = 'none';
            helpText.textContent = "Seleccione un dispositivo específico para ver su historial.";
            if(document.getElementById('chkAutoRefresh').checked) startAutoRefresh();
        } else {
            historyControls.style.display = 'block';
            helpText.textContent = "Use los controles de abajo para ver la ruta histórica de este dispositivo.";
        }
    }

    async function cargarDatosCompletos(isBackground = false) {
        const btn = document.querySelector('.btn-primary');
        if(!isBackground && btn) btn.innerHTML = '<i class="fa fa-spinner fa-spin"></i> Cargando...';

        // LÓGICA DE ÚLTIMA UBICACIÓN: 
        // Usamos MAX(id) para asegurar que obtenemos el último registro insertado
        const sql = `
            SELECT t1.* FROM MS_GPS.GPS_Reg t1
            JOIN (
                SELECT imei, MAX(id) as max_id
                FROM MS_GPS.GPS_Reg
                GROUP BY imei
            ) t2 ON t1.imei = t2.imei AND t1.id = t2.max_id
        `;

        const res = await fetchData(sql);
        
        if (res.status && res.data) {
            allDevicesData = res.data;
            actualizarSelectDispositivos(allDevicesData);
            
            // Si NO estamos en modo historial activo (viendo una ruta), actualizamos el mapa en vivo
            if (document.getElementById('sliderContainer').style.display === 'none') {
                if (document.getElementById('selectDispositivo').value !== 'TODOS') {
                    // Si es actualización automática (isBackground), NO centramos el mapa (false) para no molestar al usuario
                    // Si es manual, centramos (true)
                    filtrarMapa(!isBackground); 
                } else {
                    renderMarkersLive(allDevicesData);
                }
            }
            
            document.getElementById('deviceCountLabel').textContent = `${allDevicesData.length} Dispositivos activos`;
            actualizarDetalleSiAbierto();
        }
        
        if(!isBackground && btn) btn.innerHTML = '<i class="fa fa-sync-alt mr-2"></i> Actualizar Ahora';
    }

    function renderMarkersLive(data) {
        markersLayer.clearLayers();
        historyLayer.clearLayers(); // Limpiamos capa de historial por si acaso
        
        data.forEach(gps => {
            const lat = parseFloat(gps.latitud);
            const lng = parseFloat(gps.longitud);

            if (!isNaN(lat) && !isNaN(lng) && lat !== 0 && lng !== 0) {
                // USAR ICONO DIRECCIONAL
                const marker = L.marker([lat, lng], {
                    icon: createDirectionalIcon(gps.rumbo)
                }).addTo(markersLayer);
                
                marker.bindTooltip(`<b>${gps.imei}</b>`, { direction: 'top', offset: [0, -20] });

                marker.on('click', () => {
                    abrirDetailSidebar(gps);
                    // Sincronizar select y UI
                    document.getElementById('selectDispositivo').value = gps.imei;
                    cambiarDispositivo(); 
                });
            }
        });
    }

    // Modificado: Acepta parametro para saber si debe centrar el mapa o no
    function filtrarMapa(centerMap = true) {
        const imei = document.getElementById('selectDispositivo').value;
        if (imei === 'TODOS') {
            renderMarkersLive(allDevicesData);
        } else {
            const target = allDevicesData.find(d => d.imei === imei);
            if (target) {
                renderMarkersLive([target]);
                if (centerMap) {
                    map.flyTo([target.latitud, target.longitud], 15);
                }
            }
        }
    }

    // --- LÓGICA DE HISTORIAL (SLIDER) ---

    async function cargarHistorial() {
        const imei = document.getElementById('selectDispositivo').value;
        const fecha = document.getElementById('historyDate').value;
        const sliderContainer = document.getElementById('sliderContainer');

        if (imei === 'TODOS' || !imei) {
            alert("Seleccione un dispositivo primero.");
            return;
        }

        // 1. Detener Auto-Refresh para no interferir
        stopAutoRefresh();
        document.getElementById('chkAutoRefresh').checked = false;
        document.getElementById('liveIndicator').classList.remove('active');

        // UI Feedback
        sliderContainer.style.display = 'block';
        sliderContainer.style.opacity = '0.5';
        document.getElementById('historyTimeDisplay').textContent = "Cargando Ruta...";

        // 2. Consulta SQL: Obtener TODOS los puntos del día usando DATE(creado)
        const sql = `SELECT * FROM MS_GPS.GPS_Reg WHERE imei = '${imei}' AND DATE(creado) = '${fecha}' ORDER BY creado ASC`;
        
        const res = await fetchData(sql);

        if (res.status && res.data && res.data.length > 0) {
            historyData = res.data;
            
            // Configurar Slider
            const slider = document.getElementById('timeSlider');
            slider.max = historyData.length - 1;
            slider.value = historyData.length - 1; // Ir al final por defecto
            
            // Extraer hora de la columna creado
            const getHora = (dateStr) => {
                if(!dateStr) return "00:00";
                const parts = dateStr.split(' ');
                return parts.length > 1 ? parts[1].substring(0,5) : "00:00";
            };

            // Actualizar etiquetas info usando 'creado'
            document.getElementById('startTime').textContent = getHora(historyData[0].creado);
            document.getElementById('endTime').textContent = getHora(historyData[historyData.length-1].creado);
            document.getElementById('pointCount').textContent = historyData.length + " pts";

            // Renderizar Ruta
            renderRutaHistorial();
            
            sliderContainer.style.opacity = '1';
        } else {
            alert("No se encontraron registros para este dispositivo en la fecha seleccionada.");
            sliderContainer.style.display = 'none';
        }
    }

    function renderRutaHistorial() {
        markersLayer.clearLayers();
        historyLayer.clearLayers();

        const latlngs = [];
        
        historyData.forEach(pt => {
             const lat = parseFloat(pt.latitud);
             const lng = parseFloat(pt.longitud);
             if(lat !== 0 && lng !== 0) latlngs.push([lat, lng]);
        });

        if (latlngs.length > 0) {
            // Dibujar línea azul
            historyPolyline = L.polyline(latlngs, {color: 'blue', weight: 4, opacity: 0.7}).addTo(historyLayer);
            map.fitBounds(historyPolyline.getBounds(), {padding: [50, 50]});

            const lastPoint = latlngs[latlngs.length - 1];
            const ultimoDato = historyData[historyData.length - 1];
            
            historyMarker = L.marker(lastPoint, { 
                zIndexOffset: 1000,
                icon: createDirectionalIcon(ultimoDato.rumbo)
            }).addTo(historyLayer);
            
            moverSlider(historyData.length - 1);
        }
    }

    function moverSlider(index) {
        if (!historyData || historyData.length === 0) return;
        
        const punto = historyData[index];
        const lat = parseFloat(punto.latitud);
        const lng = parseFloat(punto.longitud);
        
        let horaStr = punto.creado;
        if(horaStr && horaStr.includes(' ')) {
            horaStr = horaStr.split(' ')[1];
        }

        if (historyMarker) {
            historyMarker.setLatLng([lat, lng]);
            historyMarker.setIcon(createDirectionalIcon(punto.rumbo));
            historyMarker.bindTooltip(`<b>${horaStr}</b>`, {permanent: false, direction: 'top'}).openTooltip();
        }

        document.getElementById('historyTimeDisplay').textContent = horaStr;
    }

    function salirModoHistorial() {
        historyLayer.clearLayers();
        historyData = [];
        document.getElementById('sliderContainer').style.display = 'none';
        cargarDatosCompletos(false); 
    }


    // --- HELPERS Y UI COMUNES ---

    function actualizarSelectDispositivos(data) {
        const select = document.getElementById('selectDispositivo');
        if (document.activeElement === select) return; 
        const valorActual = select.value;
        
        select.innerHTML = '<option value="TODOS">-- Ver Todos --</option>';
        data.sort((a, b) => a.imei.localeCompare(b.imei));

        data.forEach(d => {
            const option = document.createElement('option');
            option.value = d.imei;
            option.textContent = `${d.imei}`;
            select.appendChild(option);
        });

        if (valorActual && valorActual !== 'TODOS') {
            const exists = data.some(d => d.imei === valorActual);
            if(exists) select.value = valorActual;
            else select.value = 'TODOS';
        }
    }

    function toggleAutoRefresh() {
        if (document.getElementById('chkAutoRefresh').checked) startAutoRefresh();
        else stopAutoRefresh();
    }

    function startAutoRefresh() {
        if(refreshInterval) clearInterval(refreshInterval);
        document.getElementById('liveIndicator').classList.add('active');
        refreshInterval = setInterval(() => {
            if (document.getElementById('sliderContainer').style.display === 'none') {
                // TRUE indica que es background refresh (no mostrar spinner, no forzar zoom)
                cargarDatosCompletos(true);
            }
        }, REFRESH_RATE_MS);
    }

    function stopAutoRefresh() {
        if(refreshInterval) clearInterval(refreshInterval);
        document.getElementById('liveIndicator').classList.remove('active');
    }

    function recargarDatos(manual) {
        cargarDatosCompletos(false);
    }

    // --- MANEJO DE SIDEBARS ---
    var currentDetailImei = null;

    function toggleFilterSidebar() {
        const sb = document.getElementById('filterSidebar');
        sb.classList.toggle('active');
        if(sb.classList.contains('active')) cerrarDetailSidebar();
    }

    function abrirDetailSidebar(data) {
        currentDetailImei = data.imei;
        renderDetalleContenido(data);
        document.getElementById('detailSidebar').classList.add('active');
        if(window.innerWidth < 992) document.getElementById('filterSidebar').classList.remove('active');
    }

    function cerrarDetailSidebar() {
        document.getElementById('detailSidebar').classList.remove('active');
        currentDetailImei = null;
    }

    function actualizarDetalleSiAbierto() {
        if (!currentDetailImei) return;
        if (document.getElementById('sliderContainer').style.display !== 'none') return;

        const newData = allDevicesData.find(d => d.imei === currentDetailImei);
        if (newData) renderDetalleContenido(newData);
    }

    function renderDetalleContenido(data) {
        const title = document.getElementById('detailTitle');
        const content = document.getElementById('detailContent');
        
        const creadoStr = data.creado.replace(/-/g, '/');
        const lastUpdate = new Date(creadoStr);
        const now = new Date();
        const diffMins = Math.floor((now - lastUpdate) / 60000);

        const isRecent = diffMins <= 10;
        
        let statusHtml = '';
        if (!isRecent) {
            statusHtml = `<span class="status-pill status-err"><i class="fa fa-times-circle"></i> Desconectado</span>`;
        } else {
            statusHtml = `<span class="status-pill status-ok"><i class="fa fa-check-circle"></i> Conectado</span>`;
        }

        title.textContent = `IMEI: ${data.imei}`;
        
        content.innerHTML = `
            <div class="text-center mb-4">
                ${statusHtml}
                <div class="mt-2 text-muted small">
                    <i class="fa fa-clock"></i> ${data.creado} <br>
                    (Hace ${diffMins} min)
                </div>
            </div>
            <h6 class="text-uppercase text-muted font-weight-bold small mb-3">Información de Ubicación</h6>
            ${row('Latitud', parseFloat(data.latitud).toFixed(6))}
            ${row('Longitud', parseFloat(data.longitud).toFixed(6))}
            ${row('Velocidad', `<b>${data.velocidad}</b> km/h`)}
            ${row('Rumbo', `${data.rumbo}°`)}
            <hr>
            <h6 class="text-uppercase text-muted font-weight-bold small mb-3">Datos Técnicos</h6>
            ${row('Estado Hex', data.estado_hex || '-')}
            ${row('Cell ID', data.cellid || '-')}
            ${row('MCC / LAC', `${data.mcc || '?'} / ${data.lac || '?'}`)}
            <div class="mt-4">
                <a href="https://www.google.com/maps?q=${data.latitud},${data.longitud}" target="_blank" class="btn btn-outline-dark btn-block btn-sm">
                    <i class="fab fa-google"></i> Abrir en Google Maps
                </a>
            </div>
        `;
    }

    function row(label, value) {
        return `<div class="detail-row"><label>${label}</label><span>${value}</span></div>`;
    }
</script>