<script>
import { inject, provide, useSlots, useTemplateRef, watch } from "vue";
import { MARKER_CLUSTERER_INJECTION_KEY } from "./types";
import { bindGoogleMapsEvents, MARKER_INJECTION_KEY, useGoogleMapsResource } from "./useGoogleMapsResource";
export { MARKER_INJECTION_KEY } from "./useGoogleMapsResource";
</script>

<script setup>
const props = defineProps({
  position: { type: null, required: false },
  options: { type: Object, required: false }
});
const emit = defineEmits(["click", "drag", "dragend", "dragstart"]);
defineSlots();
const dragEvents = ["drag", "dragend", "dragstart"];
const slots = useSlots();
const markerContent = useTemplateRef("marker-content");
const markerClustererContext = inject(MARKER_CLUSTERER_INJECTION_KEY, void 0);
let gmpClickHandler;
const advancedMarkerElement = useGoogleMapsResource({
  ready: () => !slots.content || !!markerContent.value,
  async create({ mapsApi, map }) {
    if (import.meta.dev && !map.get("mapId")) {
      console.warn("[nuxt-scripts] <ScriptGoogleMapsMarker> requires the parent <ScriptGoogleMaps> to have a `mapId` set, but none was found. This usually happens when `mapOptions.styles` (JSON styles) is set, since Google Maps treats `styles` and `mapId` as mutually exclusive. Use cloud-based map styling instead: https://scripts.nuxt.com/scripts/google-maps/guides/map-styling");
    }
    await mapsApi.importLibrary("marker");
    const marker = new mapsApi.marker.AdvancedMarkerElement({
      ...props.options,
      gmpClickable: true,
      ...props.position ? { position: props.position } : {}
    });
    if (markerContent.value) {
      marker.content = markerContent.value;
    }
    if (markerClustererContext?.markerClusterer.value) {
      markerClustererContext.markerClusterer.value.addMarker(marker, true);
      markerClustererContext.requestRerender();
    } else {
      marker.map = map;
    }
    gmpClickHandler = (e) => emit("click", e);
    marker.addEventListener("gmp-click", gmpClickHandler);
    bindGoogleMapsEvents(marker, emit, {
      withPayload: dragEvents
    });
    return marker;
  },
  cleanup(marker, { mapsApi }) {
    if (gmpClickHandler) {
      marker.removeEventListener("gmp-click", gmpClickHandler);
      gmpClickHandler = void 0;
    }
    mapsApi.event.clearInstanceListeners(marker);
    if (markerClustererContext?.markerClusterer.value) {
      markerClustererContext.markerClusterer.value.removeMarker(marker, true);
      markerClustererContext.requestRerender();
    } else {
      marker.map = null;
    }
  }
});
watch(
  () => [props.position, props.options],
  () => {
    if (!advancedMarkerElement.value)
      return;
    if (props.options)
      Object.assign(advancedMarkerElement.value, props.options);
    advancedMarkerElement.value.position = props.position ?? props.options?.position;
  },
  { deep: true }
);
provide(MARKER_INJECTION_KEY, { advancedMarkerElement });
</script>

<template>
  <!-- Hidden container for #content slot — becomes the marker visual -->
  <div v-if="$slots.content" style="display: none;">
    <div ref="marker-content">
      <slot name="content" />
    </div>
  </div>
  <!-- Default slot for child components (InfoWindow, OverlayView, etc.) -->
  <slot v-if="advancedMarkerElement" />
</template>
