<template>
  <div ref="mapContainer" class="map-container"></div>
</template>

<script>
export default {
  name: 'OpenStreetMapEmbed',
  props: {
    coordinates: {
      type: Object,
      default: () => ({ latitude: 51.1657, longitude: 10.4515 })
    },
    zoom: {
      type: Number,
      default: 13,
      validator: (value) => value >= 1 && value <= 19
    },
    showMarker: {
      type: Boolean,
      default: true
    },
    markerColor: {
      type: String,
      default: '#002F54'
    },
    tileStyle: {
      type: String,
      default: 'standard',
      validator: (value) => ['standard', 'dark', 'humanitarian', 'topo'].includes(value)
    },
    customFilter: {
      type: String,
      default: ''
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '450px'
    }
  },
  data() {
    return {
      map: null,
      marker: null
    }
  },
  computed: {
    tileLayerUrl() {
      const styles = {
        standard: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        dark: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',
        humanitarian: 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
        topo: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png'
      };
      return styles[this.tileStyle] || styles.standard;
    },
    tileAttribution() {
      return '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';
    }
  },
  mounted() {
    this.initMap();
  },
  beforeUnmount() {
    if (this.map) {
      this.map.remove();
    }
  },
  watch: {
    coordinates: {
      handler(newCoords) {
        if (this.map) {
          const { latitude, longitude } = newCoords;
          this.map.setView([latitude, longitude], this.zoom);

          if (this.marker) {
            this.marker.setLatLng([latitude, longitude]);
          }
        }
      },
      deep: true
    },
    zoom(newZoom) {
      if (this.map) {
        this.map.setZoom(newZoom);
      }
    },
    showMarker(show) {
      if (this.map) {
        if (show && !this.marker) {
          this.addMarker();
        } else if (!show && this.marker) {
          this.map.removeLayer(this.marker);
          this.marker = null;
        }
      }
    },
    tileStyle() {
      if (this.map) {
        this.updateTileLayer();
      }
    }
  },
  methods: {
    async initMap() {
      // Dynamically import Leaflet to avoid SSR issues
      const L = await import('leaflet');
      await import('leaflet/dist/leaflet.css');

      const { latitude, longitude } = this.coordinates;

      this.map = L.map(this.$refs.mapContainer, {
        center: [latitude, longitude],
        zoom: this.zoom,
        zoomControl: true,
        scrollWheelZoom: true
      });

      this.updateTileLayer();

      if (this.showMarker) {
        this.addMarker();
      }
    },
    async updateTileLayer() {
      const L = await import('leaflet');

      // Remove existing tile layers
      this.map.eachLayer((layer) => {
        if (layer instanceof L.TileLayer) {
          this.map.removeLayer(layer);
        }
      });

      // Add new tile layer
      L.tileLayer(this.tileLayerUrl, {
        attribution: this.tileAttribution,
        maxZoom: 19
      }).addTo(this.map);
    },
    async addMarker() {
      const L = await import('leaflet');
      const { latitude, longitude } = this.coordinates;

      // Custom marker icon with color
      const markerHtml = `
        <svg width="25" height="41" viewBox="0 0 25 41" xmlns="http://www.w3.org/2000/svg">
          <path d="M12.5 0C5.596 0 0 5.596 0 12.5c0 9.375 12.5 28.125 12.5 28.125S25 21.875 25 12.5C25 5.596 19.404 0 12.5 0z"
                fill="${this.markerColor}" stroke="#fff" stroke-width="2"/>
          <circle cx="12.5" cy="12.5" r="4" fill="#fff"/>
        </svg>
      `;

      const customIcon = L.divIcon({
        html: markerHtml,
        className: 'custom-marker',
        iconSize: [25, 41],
        iconAnchor: [12.5, 41]
      });

      this.marker = L.marker([latitude, longitude], { icon: customIcon }).addTo(this.map);
    }
  }
}
</script>

<style scoped>
.map-container {
  width: v-bind(width);
  height: v-bind(height);
  position: relative;
  z-index: 0;
}

.map-container :deep(.leaflet-tile-pane) {
  filter: v-bind(customFilter);
}

:deep(.custom-marker) {
  background: transparent;
  border: none;
}

:deep(.leaflet-control-attribution) {
  font-size: 0.8rem;
  background: rgba(255, 255, 255, 0.8);
}
</style>