import { Component, Prop, Vue } from 'vue-facing-decorator';
import * as L from 'leaflet';
import 'leaflet/dist/leaflet.css';

@Component({
  name: 'Minimap',
})
export default class Minimap extends Vue {
  @Prop({ type: Array, required: true }) bounds!: L.LatLngBoundsLiteral;

  // private originalCenter: L.LatLngExpression = [47.71, 13.55]; // Original center
  // private originalZoom: number = 6; // Original zoom level

  /**
   * Lifecycle hook called when the component is mounted.
   * Initializes the Leaflet map, sets up base layers, and adds either a circle or rectangle
   * based on the `bounds` prop passed to the component.
   */
  mounted() {
    // Initialize the map with specific center and zoom
    const map = L.map('map', {
      center: [47.71, 13.55], // Initial center coordinates
      zoomControl: true,      // Enable zoom controls
      zoom: 6,                // Initial zoom level
      minZoom: 5,             // Minimum zoom level allowed
      maxBounds: [
        [44.0, 9.0],          // Southwest corner of the bounding box
        [51.0, 18.0]          // Northeast corner of the bounding box
      ],
      maxBoundsViscosity: 1.0 // Prevent map from being dragged outside the defined bounds
    });
  
    // Remove Leaflet logo and text
    map.attributionControl.setPrefix(false);

    // Add basemap.at tile layer to the map
    const basemapAtLayer = L.tileLayer('https://maps{s}.wien.gv.at/basemap/geolandbasemap/normal/google3857/{z}/{y}/{x}.png', {
      attribution: '<a href="https://www.basemap.at">basemap.at</a>',
      noWrap: true,
      subdomains: ['', '1', '2', '3', '4']
    }).addTo(map);
  
    // Add Esri imagery tile layer
    const esriImageryLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
      attribution: 'Tiles &copy; <a href="https://www.esri.com/" target="_blank">Esri</a>'
    });
  
    // Add Esri topo map tile layer
    const esriTopoLayer = L.tileLayer('https://server.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
      attribution: 'Tiles &copy; <a href="https://www.esri.com/" target="_blank">Esri</a>'
    });
  
    // Define available base maps for the user to toggle between
    const baseMaps = {
      //   "OpenStreetMap": openStreetMapLayer,
      "basemap.at": basemapAtLayer,
      "ESRI Imagery": esriImageryLayer,
      "ESRI Topo": esriTopoLayer
    };
  
    // Define available base maps for the user to toggle between
    L.control.layers(baseMaps).addTo(map);
  
    const [southWest, northEast] = this.bounds;
  
    if (southWest[0] === northEast[0] || southWest[1] === northEast[1]) {
      // If y_min and y_max (and x_min and x_max) are equal, generate a circle
      const center = [southWest[0], southWest[1]] as [number, number];
      // Add a CircleMarker to the map at the center of the bounds. This kind of marker is used to maintain constant size regardless of zoom level
      const circleMarker = L.circleMarker(center, {
        color: '#30D5C8',       // Outline color
        fillColor: '#336699',   // Fill color
        fillOpacity: 1,         // Opacity of the fill
        opacity: 0.5,           // Outline opacity
        weight: 10,             // Outline weight (thickness)
        radius: 10              // Radius in pixels
      }).addTo(map);
  
      // Manually create a small bounding box around the marker's center to fit bounds
      const buffer = 0.01; // Buffer size around the marker. Adjust this value to control the area around the marker
      const markerBounds = L.latLngBounds(
        [center[0] - buffer, center[1] - buffer], // Southwest corner of the bounding box
        [center[0] + buffer, center[1] + buffer]  // Northeast corner of the bounding box
      );
  
      // Add a click event handler to the CircleMarker
      circleMarker.on('click', () => {
        map.fitBounds(markerBounds, { padding: [10, 10] }); // Adjust map to fit within marker bounds
      });
  
      // Automatically adjust the map's view to fit the marker's bounds
      map.fitBounds(markerBounds, { padding: [10, 10] });
  
    } else {
      // If bounds are not equal, draw a rectangle
      const rectangle = L.rectangle(this.bounds, { 
        color: '#30D5C8', // Rectangle outline color //Alternative color: 336699
        weight: 2,        // Outline thickness
        opacity: 1        // Opacity of the rectangle outline
      }).addTo(map); 

      // Add a click event handler to the Rectangle
      rectangle.on('click', () => {
        map.fitBounds(this.bounds, { padding: [18, 18] }); // Adjust map to fit within rectangle bounds
      });
  
      // Automatically adjust the map's view to fit the rectangle's bounds with padding
      map.fitBounds(this.bounds, { padding: [18, 18] });
    }
  }
  
}