<template>
  <div style="display: none"></div>
</template>

<script setup lang="ts">
import {
  ref,
  markRaw,
  inject,
  nextTick,
  onMounted,
  onBeforeUnmount,
  useAttrs,
  defineEmits,
} from 'vue';

import { routingControlProps, setupRoutingControl } from 'functions/routingControl';
import { Utilities, InjectionKeys } from '@vue-leaflet/vue-leaflet';

import 'leaflet';
import 'leaflet-routing-machine';
import 'leaflet-routing-machine/dist/leaflet-routing-machine.css';

import type L from 'leaflet';

// ---- Emits ----
const emit = defineEmits<{
  (e: 'ready', value: L.Routing.Control): void;
}>();

// ---- Props ----
const props = defineProps(routingControlProps);

// ---- Attrs (for events) ----
const attrs = useAttrs();

// ---- Injections ----
const { UseGlobalLeafletInjection, RegisterControlInjection } = InjectionKeys;
const { WINDOW_OR_GLOBAL, assertInject, propsBinder, remapEvents } = Utilities;

const useGlobalLeaflet = inject(UseGlobalLeafletInjection, false);
const registerControl = assertInject(RegisterControlInjection);

// ---- State ----
const leafletObject = ref<L.Routing.Control | null>(null);

// ---- Setup logic ----
const { options, methods } = setupRoutingControl(props);

onMounted(async () => {
  const { routing } = useGlobalLeaflet
    ? (WINDOW_OR_GLOBAL as any).L
    : await import('leaflet/dist/leaflet-src.esm');

  const { listeners } = remapEvents(attrs);

  leafletObject.value = markRaw(routing.control(options));
  leafletObject.value.on(listeners);

  propsBinder(methods, leafletObject.value, props);
  registerControl({ leafletObject: leafletObject.value });

  await nextTick();
  emit('ready', leafletObject.value);
});

onBeforeUnmount(() => {
  if (leafletObject.value) {
    leafletObject.value.setWaypoints([]);
    leafletObject.value.remove();
  }
});
</script>
