<template>
    <div class="space-y-2">
        <button
            @click="toggleMap"
            class="flex items-center gap-2 text-sm font-bold text-accent hover:text-accent-content transition-colors"
        >
            <iconify-icon :icon="isOpen ? 'lucide:chevron-up' : 'lucide:chevron-down'"></iconify-icon>
            {{ isOpen ? 'Hide map' : 'Show map' }}
        </button>

        <div
            v-show="isOpen"
            ref="mapContainer"
            class="w-full h-72 rounded-2xl overflow-hidden border border-zinc-300 shadow-sm"
        ></div>
    </div>
</template>

<script setup>
import { ref, watch, onUnmounted, nextTick } from 'vue'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'

// Fix Leaflet default marker icon path broken by Vite
delete L.Icon.Default.prototype._getIconUrl
L.Icon.Default.mergeOptions({
    iconRetinaUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png',
    iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png',
    shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
})

const props = defineProps({
    stations: { type: Array, required: true },
})

const mapContainer = ref(null)
const isOpen = ref(false)
let mapInstance = null
let markersLayer = null

function initMap() {
    if (mapInstance || !mapContainer.value) return

    mapInstance = L.map(mapContainer.value)

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap contributors',
    }).addTo(mapInstance)

    markersLayer = L.layerGroup().addTo(mapInstance)
}

function renderMarkers() {
    if (!mapInstance || !markersLayer) return

    markersLayer.clearLayers()

    if (!props.stations.length) return

    const bounds = []

    props.stations.forEach(station => {
        const marker = L.marker([station.lat, station.lng])
            .bindPopup(`<strong>${station.name}</strong><br>${station.price}p`)
        markersLayer.addLayer(marker)
        bounds.push([station.lat, station.lng])
    })

    if (bounds.length) {
        mapInstance.fitBounds(bounds, { padding: [30, 30] })
    }
}

async function toggleMap() {
    isOpen.value = !isOpen.value

    if (isOpen.value) {
        await nextTick()
        initMap()
        mapInstance.invalidateSize()
        renderMarkers()
    }
}

watch(() => props.stations, () => {
    if (isOpen.value) {
        renderMarkers()
    }
})

onUnmounted(() => {
    if (mapInstance) {
        mapInstance.remove()
        mapInstance = null
    }
})
</script>
