<script>
    // components
    import PageTitle from "$/components/PageTitle.svelte"
    import IconLoading from "$/components/IconLoading.svelte"
    import OffcanvasParadero from "./OffcanvasParadero.svelte"

    // services
    import { getRegiones } from "$/services/regiones"
    import { getComunas } from "$/services/comunas"
    import { getMarcasParaderos } from "$/services/mapas"

    // libs
    import { onMount } from 'svelte'
    import { storeParaderos } from "$/stores/global"
    import imagenParada from '$/assets/parada.png'

    let myMap = null
    let elMap = null
    let loading = false
    let regiones = []
    let comunas = []
    let comunas_x_region = []
    let L = null
    let iconParada = null
    let markers = []
    let form = {}
    let parada = null

    cargar_regiones_comunas()

    $: myMap && crear_marcadores_por_criterio()

    onMount(() => {
        if(globalThis.L) create_map();
        cargar_paraderos_todos($storeParaderos)
    })

    function create_map() {
        if (!elMap || !globalThis.L) return;
        if (!L) L = globalThis.L;
        if (!iconParada) {
            iconParada = L.icon({
                iconUrl: imagenParada,
                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 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 cargar_regiones_comunas() {
        try {
            regiones = await getRegiones()
            comunas = await getComunas()
        } catch (error) {
            alert(error)
        }
    }

    async function cargar_paraderos_todos(data_default) {
        try {
            loading = true
            const paraderos = data_default || await getMarcasParaderos()
            storeParaderos.set(paraderos)
        } catch (error) {
            alert(error)
        } finally {
            loading = false
        }
    }

    function crear_marcadores_por_criterio() {
        if (form.id_region) {
            comunas_x_region = comunas.filter(comuna => comuna.id_region === form.id_region)
        }
        if (!$storeParaderos?.marks) {
            setTimeout(crear_marcadores_por_criterio, 1000)
            return
        }
        // 1. eliminar los marcadores anteriores
        markers.forEach(marker => marker.remove())

        // 2. filtrar resultado de marcadores
        const paraderos = $storeParaderos.marks.filter(m => {
            // filtrar por comunas de la region
            if (form.id_region && !form.id_comuna) {
                const existe = comunas_x_region.findIndex(com => com.id_comuna === m.id_comuna) !== -1
                if (!existe) return false
            }
            
            // filtrar por comuna seleccionada
            if (form.id_comuna && m.id_comuna !== form.id_comuna) return false
            
            // filtrar por texto de busqueda
            if (form.search && m.location.toUpperCase().indexOf(form.search.toUpperCase()) === -1) return false

            // filtro coincide a criterio
            return true
        })

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

            marker.bindTooltip(html)

            marker.on('click', function() {
                parada = { ...mark }
            })
            markers.push(marker)
        }

        // 4. centrar mapa
        if (myMap && paraderos.length) {
            const { lat, lng } = paraderos[0].position
            myMap.setView([ lat, lng ],16)
            const bounds = myMap.getBounds()
            paraderos.forEach(el => bounds.extend(el.position))
            myMap.fitBounds(bounds)
        }
    }


    function run_search_text() {
        form.time_search && clearTimeout(form.time_search)
        form.time_search = setTimeout(() => crear_marcadores_por_criterio(), 1000)
    }
</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">
        <PageTitle>
            {#if loading}<IconLoading />{/if}
            Paraderos
        </PageTitle>
    </div>
    <div class="col-md-auto">
        <div class="input-group mb-sm-3">
            <div class="input-group-text">Región</div>
            <select bind:value={form.id_region} class="form-select" on:change={crear_marcadores_por_criterio}>
                <option value=""></option>
                {#each regiones as r}
                <option value={r.id_region}>{r.nombre_region}</option>
                {/each}
            </select>
        </div>
    </div>
    <div class="col-md-auto">
        <div class="input-group mb-sm-3">
            <div class="input-group-text">Comuna</div>
            <select bind:value={form.id_comuna} class="form-select" on:change={crear_marcadores_por_criterio}>
                <option value=""></option>
                {#each comunas_x_region as c}
                <option value={c.id_comuna}>{c.nombre_comuna}</option>
                {/each}
            </select>
        </div>
    </div>
    <div class="col-md-auto">
        <div class="input-group mb-sm-3">
            <input type="search" bind:value={form.search} class="form-control" on:input={run_search_text}>
            <div class="input-group-text"><i class="bi bi-search"></i></div>
        </div>
    </div>
</div>

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

<OffcanvasParadero {parada} on:close={() => parada = null} />