import L from "leaflet";

export class OverlappingMarkerSpiderfier {
  constructor(map, options = {}) {
    this.map = map;
    this.markers = [];
    this.markerListeners = [];
    this.keepSpiderfied = options.keepSpiderfied || false;

    // Basiseinstellungen für die Distanz und die Zoomstufenabhängigkeit
    this.baseNearbyDistance = options.nearbyDistance || 20;
    this.nearbyDistance = this.baseNearbyDistance; // Initialwert setzen

    this.circleSpiralSwitchover = options.circleSpiralSwitchover || 9;
    this.circleFootSeparation = options.circleFootSeparation || 25;
    this.circleStartAngle = options.circleStartAngle || Math.PI / 6;
    this.spiralFootSeparation = options.spiralFootSeparation || 28;
    this.spiralLengthStart = options.spiralLengthStart || 11;
    this.spiralLengthFactor = options.spiralLengthFactor || 5;
    this.legWeight = options.legWeight || 1.5;
    this.legColors = options.legColors || {
      usual: "#222",
      highlighted: "#f00",
    };

    this.initMarkerArrays();
    this.map.on("click", () => this.unspiderfy());
    this.map.on("zoomend", () => this.unspiderfy());
  }

  initMarkerArrays() {
    this.markers = [];
    this.markerListeners = [];
  }

  addMarker(marker) {
    if (!marker._oms) {
      marker._oms = {}; // Stellt sicher, dass _oms ein Objekt ist
    }

    const listener = () => {
      this.spiderListener(marker);
    };

    marker.on("click", listener);
    this.markerListeners.push(listener);
    this.markers.push(marker);

    return this;
  }

  spiderListener(marker) {
    const spidered = marker._oms.spidered;
    if (!spidered) {
      const nearMarkers = this.nearbyMarkers(marker);
      if (nearMarkers.length > 1) {
        this.spiderfy(nearMarkers);
      }
    } else {
      this.unspiderfy(); // Schließt alle gespiderfied Marker, wenn einer erneut geklickt wird
    }
  }

  nearbyMarkers(marker) {
    return this.markers.filter((m) => {
      const distance = this.map.distance(marker.getLatLng(), m.getLatLng());
      return distance < this.nearbyDistance && marker !== m;
    });
  }
  //---------------------------------------------------------------------------------------------
  spiderfy(markers) {
    const centerPt = this.map.latLngToLayerPoint(markers[0].getLatLng());

    markers.forEach((marker, i) => {
      const angle = this.circleStartAngle + (i * 2 * Math.PI) / markers.length;
      const legLength = this.circleFootSeparation * (2 + i / markers.length);
      const newPt = L.point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle));
      const newLatLng = this.map.layerPointToLatLng(newPt);

      if (!marker._oms) {
        marker._oms = {};
      }

      marker._oms.usualPosition = marker.getLatLng();
      marker._oms.spidered = true;

      // Zeichne eine Linie zwischen ursprünglicher und neuer Position
      const leg = L.polyline([marker._oms.usualPosition, newLatLng], {
        color: this.legColors.usual,
        weight: this.legWeight,
      }).addTo(this.map);

      marker._oms.leg = leg; // Speichert die Linie im Marker-Objekt

      marker.setLatLng(newLatLng);
      marker.setZIndexOffset(1000);
    });
  }

  //---------------------------------------------------------------------------------------------
  unspiderfy() {
    this.markers.forEach((marker) => {
      if (marker._oms && marker._oms.spidered) {
        // Falls eine Linie existiert, entferne sie aus der Karte
        if (marker._oms.leg) {
          this.map.removeLayer(marker._oms.leg);
          marker._oms.leg = null;
        }

        marker.setLatLng(marker._oms.usualPosition);
        marker.setZIndexOffset(0);
        marker._oms.spidered = false;
      }
    });
    // 🔥 Künstliches Click-Event auslösen, um die UI zu aktualisieren
    setTimeout(() => {
      this.map.fire("click");
      console.log("Click-Event ausgelöst in OverlappingMarkerspiderfier.js in unspiderfy ");
    }, 10); // Kurze Verzögerung, um sicherzustellen, dass die UI neu gerendert wird
  }

  //---------------------------------------------------------------------------------------------
}
