/** Pinia store for route management */
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { Route, BusStop } from '@/types'
import { routesService } from '@/services/routesService'

export const useRouteStore = defineStore('route', () => {
    const selectedRouteId = ref<string | null>(null)
    const selectedRouteName = ref<string | null>(null)
    const selectedRouteStops = ref<BusStop[]>([])
    const allRoutes = ref<Route[]>([])
    const isLoadingRoutes = ref(false)
    const isLoadingStops = ref(false)
    const error = ref<string | null>(null)
    const wasSelectedFromMap = ref(false)
    const lastFetched = ref<number>(0) // ⚡ CACHÉ ESTÁTICO RUTAS
    const stopsCache = ref<Map<string, { fetchedAt: number, stops: BusStop[] }>>(new Map()) // ⚡ CACHÉ ESTÁTICO PARADAS

    const hasSelectedRoute = computed(() => selectedRouteId.value !== null && selectedRouteName.value !== null)

    // Safety: nunca más de 12s cargando (protección contra thread congelado por OS al apagar pantalla)
    let _routesSafetyTimer: ReturnType<typeof setTimeout> | null = null
    let _stopsSafetyTimer: ReturnType<typeof setTimeout> | null = null
    function _startRoutesSafety() {
        if (_routesSafetyTimer) clearTimeout(_routesSafetyTimer)
        _routesSafetyTimer = setTimeout(() => {
            if (isLoadingRoutes.value) {
                console.warn('SIB | routeStore: routes safety timeout — reseteando isLoadingRoutes')
                isLoadingRoutes.value = false
            }
        }, 12000)
    }
    function _startStopsSafety() {
        if (_stopsSafetyTimer) clearTimeout(_stopsSafetyTimer)
        _stopsSafetyTimer = setTimeout(() => {
            if (isLoadingStops.value) {
                console.warn('SIB | routeStore: stops safety timeout — reseteando isLoadingStops')
                isLoadingStops.value = false
            }
        }, 12000)
    }

    async function loadRoutes(filters?: { originCity?: string, destinationCity?: string }, force = false, isBackground = false) {
        const CACHE_TIME = 1000 * 60 * 15; // 15 minutos
        const now = Date.now();

        // Guard: Si ya se están cargando rutas y NO estamos en background, omitir
        // Si estamos en background, podemos sobreescribir la carga sin mostrar spinner
        if (isLoadingRoutes.value && !isBackground) return;

        // Si no forzamos, no hay filtros raros, ya tenemos rutas y aún no expira el caché, omitir llamada.
        // Se respeta en background también porque descargar docenas de rutas traba el Javascript en móviles.
        if (!force && !filters && allRoutes.value.length > 0 && (now - lastFetched.value < CACHE_TIME)) {
            return
        }

        if (!isBackground) {
            isLoadingRoutes.value = true
            _startRoutesSafety()
        }
        error.value = null
        try {
            allRoutes.value = await routesService.getAllRoutes(filters)
            if (!filters) lastFetched.value = now; // Solo actualizar timer si es un request general limio
        } catch (e) {
            error.value = e instanceof Error ? e.message : 'Failed to load routes'
            console.error('Error loading routes:', e)
        } finally {
            if (!isBackground) {
                if (_routesSafetyTimer) { clearTimeout(_routesSafetyTimer); _routesSafetyTimer = null }
                isLoadingRoutes.value = false
            }
        }
    }

    async function loadRouteStops(routeId: string, force = false): Promise<BusStop[]> {
        const CACHE_TIME = 1000 * 60 * 15; // 15 minutos
        const now = Date.now();

        if (stopsCache.value.has(routeId) && !force) {
            const cacheEntry = stopsCache.value.get(routeId)!;
            if (now - cacheEntry.fetchedAt < CACHE_TIME) {
                selectedRouteStops.value = cacheEntry.stops;
                return cacheEntry.stops;
            }
        }

        if (isLoadingStops.value) return [];
        isLoadingStops.value = true
        error.value = null
        _startStopsSafety()
        try {
            const stops = await routesService.getRouteStops(routeId)
            selectedRouteStops.value = stops
            stopsCache.value.set(routeId, { fetchedAt: now, stops })
            return stops
        } catch (e) {
            error.value = e instanceof Error ? e.message : 'Failed to load route stops'
            console.error('Error loading route stops:', e)
            selectedRouteStops.value = []
            return []
        } finally {
            if (_stopsSafetyTimer) { clearTimeout(_stopsSafetyTimer); _stopsSafetyTimer = null }
            isLoadingStops.value = false
        }
    }

    async function selectRoute(routeId: string, routeName: string) {
        if (selectedRouteId.value === routeId) return
        selectedRouteId.value = routeId
        selectedRouteName.value = routeName
        selectedRouteStops.value = [] // Limpia para forzar recarga atómica en la vista
    }

    // Watcher manual para wasSelectedFromMap ya que se cambia en varios sitios
    function setWasSelectedFromMap(val: boolean) {
        wasSelectedFromMap.value = val
    }

    function clearSelection() {
        selectedRouteId.value = null
        selectedRouteName.value = null
        selectedRouteStops.value = []
        wasSelectedFromMap.value = false
    }

    return {
        selectedRouteId,
        selectedRouteName,
        selectedRouteStops,
        allRoutes,
        isLoadingRoutes,
        isLoadingStops,
        error,
        wasSelectedFromMap,
        hasSelectedRoute,
        loadRoutes,
        loadRouteStops,
        selectRoute,
        setWasSelectedFromMap,
        clearSelection,
    }
}, {
    persist: {
        pick: ['selectedRouteId', 'selectedRouteName', 'wasSelectedFromMap', 'allRoutes']
    }
})

