<script>
    // componentes
    import PageTitle from "$/components/PageTitle.svelte";

    import imagenPartida from '$/assets/partida.png'
    import imagenTermino from '$/assets/termino.png'
    import imagenParada from '$/assets/parada.png'
    import imagenAutobus from '$/assets/autobus.png'
    import { onMount } from "svelte";

    // servicios
    import { getRutas } from "$/services/mapas";
    import ModalLetreroLUR from "./ModalLetreroLUR.svelte";
    import FiltroRutas from "./FiltroRutas.svelte";
    import { getBusesLinea, getParaderosLinea } from "$/services/lineas";

    let myMap = null
    let elMap = null
    
    let loading = false
    let polyline = null
    let iconPartida = null
    let iconTermino = null
    let iconParada = null
    let iconAutobus = null
    let L = null // leaflet.js
    let marker1 = null
    let marker2 = null

    let showLetrero = false
    
    let id_operador = ''
    let id_linea = ''
    let codigo = null
    let ver_buses = false
    let ver_paraderos = false
    let markers_paraderos = []
    let markers_buses = []
    let timeInterval = null
    let fileproto = null
    let loading_proto = false

    onMount(() => {
        create_map()

        return () => {
            timeInterval && globalThis.clearInterval(timeInterval)
        }
    })

    function create_map() {
        if (!elMap || !globalThis.L) return;
        if (!L) L = globalThis.L;
        if (!iconPartida) {
            iconPartida = L.icon({
                iconUrl: imagenPartida,
                iconSize: [40, 40],
                iconAnchor: [20, 40],
                popupAnchor: [0, -20]
            })
        }
        if (!iconTermino) {
            iconTermino = L.icon({
                iconUrl: imagenTermino,
                iconSize: [40, 40],
                iconAnchor: [20, 40],
                popupAnchor: [0, -20]
            })
        }
        if (!iconParada) {
            iconParada = L.icon({
                iconUrl: imagenParada,
                iconSize: [32, 32],
                iconAnchor: [16, 32],
                popupAnchor: [0, -16]
            })
        }
        if (!iconAutobus) {
            iconAutobus = L.icon({
                iconUrl: imagenAutobus,
                iconSize: [32, 32],
                iconAnchor: [16, 32],
                popupAnchor: [0, -16]
            })
        }
        if (!myMap) {
            myMap = L.map(elMap)
            L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                { attribution: '&copy; <a target="_blank" href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' }
            ).addTo(myMap);
        }

        // obtener coordenadas actuales
        // centrar mapa en coordenadas del navegador
        navigator.geolocation.getCurrentPosition(
            ({ coords }) => {
                const { latitude, longitude } = coords;
                myMap.setView([latitude, longitude], 16);
            },
            (error) => console.log({ error })
        )
    }

    async function onMostrarRuta(id_operador, id_linea) {
        try {
            loading = true
            timeInterval && globalThis.clearInterval(timeInterval)
            polyline && polyline.remove()
            marker1 && marker1.remove()
            marker2 && marker2.remove()

            if (!id_operador || !id_linea) return;
            const data = await getRutas({ id_linea })

            const coordenadas = data.positions.map(({ shape_pt_lat, shape_pt_lon}) => [shape_pt_lat, shape_pt_lon])
            polyline = L.polyline(coordenadas, { color: 'red' }).addTo(myMap)
            myMap.fitBounds(polyline.getBounds());

            if (coordenadas) {
                marker1 = L.marker(coordenadas[0], { icon: iconPartida }).addTo(myMap)
                marker1.bindTooltip('Inicio')
                marker2 = L.marker(coordenadas[coordenadas.length -1], { icon: iconTermino }).addTo(myMap)
                marker2.bindTooltip('Termino')
            }
            
        } catch (error) {
            alert(error)
        } finally {
            loading = false;
        }
    }


    async function onMostrarParaderos(ver_paraderos) {
        // 1. eliminar marcadores anteriores
        markers_paraderos.forEach(marker => marker.remove())

        if (!ver_paraderos || !id_linea) return;
        
        const paraderos = await getParaderosLinea(id_linea)

        // 2. crear marcadores
        for (let mark of paraderos) {
            const { stop_lat: lat, stop_lon: lng } = mark
            const marker = L.marker([lat, lng], { icon: iconParada }).addTo(myMap)
            const { id_paradero: title, stop_name: location } = mark;
            const html = `${title}<br>${location}`

            marker.bindTooltip(html)
            markers_paraderos.push(marker)
        }
    }

    async function onMostrarBuses(ver_buses) {

        if (!ver_buses && timeInterval) {
            globalThis.clearInterval(timeInterval)
            timeInterval = null
        }

        if (!ver_buses || !id_linea) {
            markers_buses.forEach(marker => marker.remove())
            fileproto = null
            return;
        }
        
        loading_proto = true
        try {
            const { fileproto: nuevoNombre, buses } = await getBusesLinea(id_linea)
            if (nuevoNombre !== fileproto) {
                // guardo el nombre del archivo proto
                fileproto = nuevoNombre
    
                // 1. eliminar marcadores anteriores
                markers_buses.forEach(marker => marker.remove())
        
                // 2. crear marcadores
                for (let mark of buses) {
                    const { latitude: lat, longitude: lng } = mark
                    const marker = L.marker([lat, lng], { icon: iconAutobus }).addTo(myMap)
                    const html = `${mark.Patente_vehiculo}<br>Velocidad: ${mark.speed}`
        
                    marker.bindTooltip(html)
                    markers_buses.push(marker)
                }
            }
        } catch (error) {
            console.log({ error })
        } finally {
            loading_proto = false
        }

        // actualizar posicion de buses cada 45 segundos
        if (!timeInterval) {
            timeInterval = globalThis.setInterval(() => onMostrarBuses(true), 45000)
        }
        
    }



    $: onMostrarRuta(id_operador, id_linea)
    $: onMostrarParaderos(ver_paraderos)
    $: onMostrarBuses(ver_buses)
</script>

<svelte:head>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" on:load={create_map}></script>
</svelte:head>


<div class="row">
    <div class="col-md-auto">
        <PageTitle {loading}>
            Rutas
        </PageTitle>
    </div>

    <div class="col-md">
        <FiltroRutas
            bind:id_operador={id_operador}
            bind:id_linea={id_linea}
            bind:codigo={codigo}
            bind:ver_buses={ver_buses}
            bind:ver_paraderos={ver_paraderos}
            loading={loading_proto}
        />
        
    </div>

    {#if id_operador && codigo}
        <div class="col-auto">
            <button class="btn btn-secondary" on:click|preventDefault={() => showLetrero = true}>
                Ver Letrero
            </button>
        </div>
    {/if}
</div>

<div class="card">
    <div class="card-body">
        <div bind:this={elMap} style="height: 100vh;"></div>
    </div>
</div>

{#if showLetrero}
    <ModalLetreroLUR {codigo} on:close={() => showLetrero = false} />
{/if}