import { ref } from 'vue'; import { supabase } from '@/supabase'; import type { BusStop } from '@/types'; export interface BusETA { horario_id: string; hora_salida: string; etaMinutos: number; estado: 'próximo' | 'en_camino' | 'pasó'; } export function useETA() { const busesActivos = ref([]); const cargando = ref(false); const calcularETA = async (ruta_id: string, parada_cercana: BusStop) => { cargando.value = true; busesActivos.value = []; try { // 1. Obtener horarios activos de la ruta para el día de hoy const diaActual = new Date().getDay(); // 0 = Domingo, 1 = Lunes... const dias = ['domingo', 'lunes', 'martes', 'miercoles', 'jueves', 'viernes', 'sabado']; const diaString = dias[diaActual]; const tipoDia = (diaActual === 0 || diaActual === 6) ? 'weekend' : 'weekday'; // Consulta flexible a supabase const { data: horarios, error } = await supabase .from('bus_schedules') .select('*') .eq('route_id', ruta_id) .eq('is_active', true); if (error) throw error; const horariosHoy = (horarios || []).filter(h => { if (h.dias_operacion) { return h.dias_operacion.includes('todos') || h.dias_operacion.includes(diaString); } return h.schedule_type === tipoDia || h.schedule_type === 'todos' || !h.schedule_type; }); // 2. Parámetros físicos e información horaria const VELOCIDAD_PROMEDIO_KMH = 30; // velocidad promedio 30 km/h // Distancia promedio en km entre la parada de origen (índice 0) hasta llegar a esta. // Si la base de datos no tiene un "orden" numérico, usamos índice o un estimado global de 0.5km por orden de parada. const ordenParada = typeof parada_cercana.stop_order === 'number' ? parada_cercana.stop_order : 1; const DISTANCIA_PROMEDIO_PARADA_KM = 0.5; // asumiendo que cada parada dista 500m const DISTANCIA_TOTAL_RUTA_KM = 15; // Estimado ruta ciudad const ahora = new Date(); const horasAhora = ahora.getHours(); const minsAhora = ahora.getMinutes(); const tiempoActualMinutos = horasAhora * 60 + minsAhora; const resultados: BusETA[] = []; for (const h of horariosHoy) { const horaSalida = h.departure_time || h.hora_salida; if (!horaSalida) continue; const [hSalidaStr, mSalidaStr] = horaSalida.split(':'); const tiempoSalidaMins = parseInt(hSalidaStr, 10) * 60 + parseInt(mSalidaStr, 10); const tiempoTranscurridoMins = tiempoActualMinutos - tiempoSalidaMins; // ¿Qué tan lejos está la parada del usuario desde el inicio? const distanciaParadaUsuario = ordenParada * DISTANCIA_PROMEDIO_PARADA_KM; // Si el bus sale en el futuro if (tiempoTranscurridoMins < 0) { const tiempoA_ParadaMins = (distanciaParadaUsuario / VELOCIDAD_PROMEDIO_KMH) * 60; const etaReal = Math.abs(tiempoTranscurridoMins) + tiempoA_ParadaMins; resultados.push({ horario_id: h.id, hora_salida: horaSalida.slice(0, 5), // Solo HH:mm etaMinutos: Math.round(etaReal), estado: 'próximo' }); } else { // El bus ya salió. ¿Dónde está? const kmsRecorridos = (tiempoTranscurridoMins / 60) * VELOCIDAD_PROMEDIO_KMH; // Ya pasó la parada if (kmsRecorridos > distanciaParadaUsuario) { // Si no ha terminado la ruta general if (kmsRecorridos <= DISTANCIA_TOTAL_RUTA_KM) { resultados.push({ horario_id: h.id, hora_salida: horaSalida.slice(0, 5), etaMinutos: 0, estado: 'pasó' }); } } else { // En camino const kmsRestantes = distanciaParadaUsuario - kmsRecorridos; const etaMinutos = (kmsRestantes / VELOCIDAD_PROMEDIO_KMH) * 60; resultados.push({ horario_id: h.id, hora_salida: horaSalida.slice(0, 5), etaMinutos: Math.round(etaMinutos), estado: 'en_camino' }); } } } // Ordenar por prioridad (en_camino < próximo < pasó) y tiempo resultados.sort((a, b) => { if (a.estado === 'pasó' && b.estado !== 'pasó') return 1; if (b.estado === 'pasó' && a.estado !== 'pasó') return -1; return a.etaMinutos - b.etaMinutos; }); busesActivos.value = resultados.slice(0, 3); // Max 3 buses } catch (e) { console.error("Error calculando ETA", e); } finally { cargando.value = false; } }; return { calcularETA, busesActivos, cargando }; }