import { useMap } from "@vis.gl/react-google-maps";
import { useEffect, useRef, useState } from "react";
import IGMapPoi from "../../types/IGMapPoi";
import MapMarker from "./MapMarker";
import {
  MarkerClusterer,
  DefaultRenderer,
  Cluster,
  Marker,
} from "@googlemaps/markerclusterer";

class CustomMarkerRenderer extends DefaultRenderer {
  render({
    count,
    position,
  }: Cluster): google.maps.marker.AdvancedMarkerElement {
    const svgElement = document.createElement("div");
    svgElement.innerHTML = `
      <svg fill="white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="50" height="50">
        <circle cx="120" cy="120" opacity="1" r="70" />
      </svg>
      <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: black; font-size: 12px; font-weight: bold;">
        ${count}
      </div>`;

    const marker = new google.maps.marker.AdvancedMarkerElement({
      position,
      content: svgElement,
      zIndex: Math.max(1000, count),
    });

    return marker;
  }
}

export default function GoogleMapMarkers({
  data,
  filter,
}: {
  data: IGMapPoi[];
  filter: string;
}) {
  const map = useMap();
  const [markers, setMarkers] = useState<{ [key: string]: Marker }>({});
  const [selectedMarker, setSelectedMarker] = useState<number | null>(null);
  const clusterer = useRef<MarkerClusterer | null>(null);

  useEffect(() => {
    if (!map) return;
    if (!clusterer.current) {
      clusterer.current = new MarkerClusterer({
        map: map,
        renderer: new CustomMarkerRenderer(),
      });
    }
  }, [map]);

  useEffect(() => {
    clusterer.current?.clearMarkers();
    clusterer.current?.addMarkers(Object.values(markers));
  }, [markers]);

  const setMarkerRef = (marker: Marker | null, key: string) => {
    if (marker && markers[key]) return;
    if (!marker && !markers[key]) return;

    setMarkers((prev) => {
      if (prev[key] === marker) return prev;

      if (marker) {
        return { ...prev, [key]: marker };
      } else {
        const newMarkers = { ...prev };
        delete newMarkers[key];
        return newMarkers;
      }
    });
  };

  return (
    <>
      {data.map(
        (poi: IGMapPoi, index: number) =>
          (filter === poi.type || filter === "All") && (
            <MapMarker
              key={index}
              markerKey={index}
              poi={poi}
              setMarkerRef={setMarkerRef}
              isSelected={selectedMarker === index}
              setSelectedMarker={setSelectedMarker}
            >
              {poi.customMarker}
            </MapMarker>
          )
      )}
    </>
  );
}
