import { ref } from 'vue';

import { useMapState } from './useMapState';

export interface Parada {
    id: number;
    nombre: string;
    latitud: number;
    longitud: number;
    orden: number;
}

export function useDirectionsRoute() {
    const estasCargando = ref<boolean>(false);
    const errorRuta = ref<string | null>(null);
    const { registrarPolyline, polylines } = useMapState();

    // Limpia los tramos anteriores dibujados en el mapa
    const limpiarRuta = () => {
        if (polylines.value.length > 0) {
            polylines.value.forEach((polyline) => {
                polyline.setMap(null);
            });
            polylines.value = [];
        }
        errorRuta.value = null;
    };

    // Función utilitaria para pausar ejecución
    const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

    const trazarRuta = async (paradas: Parada[], map: google.maps.Map, isPast: boolean = false) => {
        if (!paradas || paradas.length < 2) {
            errorRuta.value = 'Se requieren al menos 2 paradas para trazar una ruta.';
            return;
        }

        // NOTA: No llamamos a limpiarRuta() aquí para poder encadenar llamadas (dibujar fondo + trazado activo)
        estasCargando.value = true;
        errorRuta.value = null;

        try {
            // Importar librerías necesarias de la nueva API
            const { RoutesService } = await google.maps.importLibrary("routes") as any;
            const routeService = new RoutesService();

            // Límite de la API de Google Maps Routes: Origen, Destino, y hasta 25 intermediates
            const maxPuntosPorChunk = 25;
            const overlaps = 1;

            for (let i = 0; i < paradas.length - 1; i += (maxPuntosPorChunk - overlaps)) {
                const chunk = paradas.slice(i, i + maxPuntosPorChunk);
                if (chunk.length < 2) break;

                const origin = {
                    location: {
                        latLng: {
                            latitude: chunk[0]!.latitud,
                            longitude: chunk[0]!.longitud
                        }
                    }
                };

                const destination = {
                    location: {
                        latLng: {
                            latitude: chunk[chunk.length - 1]!.latitud,
                            longitude: chunk[chunk.length - 1]!.longitud
                        }
                    }
                };

                const intermediates = chunk.slice(1, -1).map(p => ({
                    location: {
                        latLng: {
                            latitude: p.latitud,
                            longitude: p.longitud
                        }
                    }
                }));

                try {
                    const response = await routeService.computeRoutes({
                        origin,
                        destination,
                        intermediates,
                        travelMode: 'DRIVE' as any, // 'DRIVE' es el nuevo estandar en computeRoutes
                        routingPreference: 'TRAFFIC_UNAWARE' as any,
                        polylineQuality: 'HIGH_QUALITY' as any,
                        polylineEncoding: 'ENCODED_POLYLINE' as any,
                    });

                    if (response.routes && response.routes.length > 0) {
                        const route = response.routes[0];
                        if (route.polyline && route.polyline.encodedPolyline) {
                            const path = google.maps.geometry.encoding.decodePath(route.polyline.encodedPolyline);

                            const polyline = new google.maps.Polyline({
                                path: path,
                                map: map,
                                strokeColor: isPast ? '#9CA3AF' : '#FBBF24', // Gris para lo lejano, Amarillo para lo cercano
                                strokeWeight: isPast ? 4 : 6,
                                strokeOpacity: isPast ? 0.6 : 1.0,
                                icons: isPast ? [{
                                    icon: { path: 'M 0,-1 0,1', strokeOpacity: 1, scale: 2 },
                                    offset: '0',
                                    repeat: '10px'
                                }] : []
                            });

                            registrarPolyline(polyline);
                        }
                    }
                } catch (err: any) {
                    console.warn(`SIBU | Tramo ${i} falló con Routes API: `, err);
                }

                await delay(200);
            }
        } catch (err: any) {
            errorRuta.value = `Error crítico al trazar la ruta: ${err.message || String(err)}`;
            console.error(errorRuta.value);
        } finally {
            estasCargando.value = false;
        }
    };

    return {
        trazarRuta,
        limpiarRuta,
        estasCargando,
        errorRuta
    };
}
