<template>
  <div id="map" class="w-full h-full rounded-lg shadow-md"></div>
</template>

<script>
import { ref, onMounted, onUnmounted, watch } from 'vue'
import L from 'leaflet'

export default {
  name: 'MapView',
  props: {
    tracks: {
      type: Array,
      default: () => []
    },
    selectedTrackIndex: {
      type: Number,
      default: null
    }
  },
  setup(props) {
    const map = ref(null)
    const trackLayers = ref([])
    const hasAutoFitted = ref(false)

    const getLocationFromIP = async () => {
      try {
        const response = await fetch('https://ipapi.co/json/')
        const data = await response.json()
        return [data.latitude, data.longitude]
      } catch (error) {
        console.log('Could not get location from IP:', error)
        // Default to San Francisco for localhost/fallback
        return [37.7749, -122.4194]
      }
    }

    const getTrackColor = (index) => {
      const colors = [
        '#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7',
        '#DDA0DD', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E9'
      ]
      return colors[index % colors.length]
    }

    const renderTracks = () => {
      // Clear existing track layers and popups
      trackLayers.value.forEach(layer => {
        map.value.removeLayer(layer)
      })
      trackLayers.value = []
      
      // Close any existing popups
      map.value.closePopup()

      if (!props.tracks || props.tracks.length === 0) return

      const allBounds = []
      let selectedTrackBounds = []
      let selectedTrackPopupOpened = false

      props.tracks.forEach((track, trackIndex) => {
        const color = getTrackColor(trackIndex)
        const isSelected = props.selectedTrackIndex === trackIndex
        
        track.segments.forEach(segment => {
          if (segment.points && segment.points.length > 0) {
            const latLngs = segment.points.map(point => [point.lat, point.lng])
            
            const polyline = L.polyline(latLngs, {
              color: color,
              weight: isSelected ? 8 : 3,
              opacity: isSelected ? 1.0 : 0.6,
              zIndexOffset: isSelected ? 1000 : 0
            }).bindPopup(`
              <div class="font-medium">${track.name}</div>
              <div class="text-sm text-gray-600 mt-1">
                Distance: ${(track.stats?.distance / 1000 || 0).toFixed(1)} km<br>
                Duration: ${Math.floor((track.stats?.duration || 0) / 3600)}:${Math.floor(((track.stats?.duration || 0) % 3600) / 60).toString().padStart(2, '0')}<br>
                Avg Speed: ${track.stats?.avgSpeed || 0} km/h
              </div>
            `)

            polyline.addTo(map.value)
            trackLayers.value.push({ polyline, trackIndex })
            
            // Open popup for selected track (only for first segment)
            if (isSelected && !selectedTrackPopupOpened) {
              // Find the northernmost point (highest latitude)
              const northernmostPoint = latLngs.reduce((north, current) => 
                current[0] > north[0] ? current : north
              )
              
              // Create popup at northernmost point
              const popup = L.popup()
                .setLatLng(northernmostPoint)
                .setContent(`
                  <div class="font-medium">${track.name}</div>
                  <div class="text-sm text-gray-600 mt-1">
                    Distance: ${(track.stats?.distance / 1000 || 0).toFixed(1)} km<br>
                    Duration: ${Math.floor((track.stats?.duration || 0) / 3600)}:${Math.floor(((track.stats?.duration || 0) % 3600) / 60).toString().padStart(2, '0')}<br>
                    Avg Speed: ${track.stats?.avgSpeed || 0} km/h
                  </div>
                `)
                .openOn(map.value)
              
              selectedTrackPopupOpened = true
            }
            
            // Add bounds for this segment
            allBounds.push(...latLngs)
            
            // Collect bounds for selected track
            if (isSelected) {
              selectedTrackBounds.push(...latLngs)
            }
          }
        })
      })

      // Focus on selected track if one is selected
      if (selectedTrackBounds.length > 0) {
        const selectedGroup = L.latLngBounds(selectedTrackBounds)
        
        // Add extra padding at the top to accommodate popup
        // Popup is roughly 80-100px tall, so add more top padding
        map.value.fitBounds(selectedGroup, { 
          paddingTopLeft: [50, 120], // Extra top padding for popup
          paddingBottomRight: [50, 50] 
        })
      } else if (allBounds.length > 0 && !hasAutoFitted.value) {
        // Only auto-fit to all tracks on initial load, not when deselecting
        const group = new L.featureGroup(trackLayers.value.map(item => item.polyline))
        map.value.fitBounds(group.getBounds(), { padding: [20, 20] })
        hasAutoFitted.value = true
      }
    }

    const initMap = async () => {
      const coords = await getLocationFromIP()
      
      map.value = L.map('map').setView(coords, 10)

      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
      }).addTo(map.value)

      // Initial track rendering
      renderTracks()
    }

    // Watch for track changes and selection changes
    watch(() => props.tracks, renderTracks, { deep: true })
    watch(() => props.selectedTrackIndex, renderTracks)

    onMounted(() => {
      initMap()
    })

    onUnmounted(() => {
      if (map.value) {
        map.value.remove()
      }
    })

    return {
      map
    }
  }
}
</script>