<template>
  <div v-if="props.address.isNoAddress" class="alert alert-info">
    Cette adresse est incomplète. La position géographique est approximative.
  </div>
  <div
    v-if="props.address.point !== null"
    class="address_details_map"
    ref="map_div"
  ></div>
  <p>
    Voir sur
    <a :href="makeUrlGoogleMap(props.address)" target="_blank">Google Maps</a>
    <a :href="makeUrlOsm(props.address)" target="_blank">OSM</a>
  </p>
</template>

<script lang="ts" setup>
import { onMounted, ref } from "vue";
import "leaflet/dist/leaflet.css";
import markerIconPng from "leaflet/dist/images/marker-icon.png";
import L, { LatLngExpression, LatLngTuple } from "leaflet";
import { Address, Point } from "../../../../types";

const lonLatForLeaflet = (point: Point): LatLngTuple => {
  return [point.coordinates[1], point.coordinates[0]];
};

export interface MapProps {
  address: Address;
}

const props = defineProps<MapProps>();

const map_div = ref<HTMLDivElement | null>(null);
let map: L.Map | null = null;
let marker: L.Marker | null = null;

onMounted(() => {
  if (map_div.value === null) {
    // there is no map div when the address does not have any Point
    return;
  }

  if (props.address.point !== null) {
    map = L.map(map_div.value);
    map.setView(lonLatForLeaflet(props.address.point), 18);

    L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
      attribution:
        '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
    }).addTo(map);

    const markerIcon = L.icon({
      iconUrl: markerIconPng,
      iconAnchor: [12, 41],
    });

    marker = L.marker(lonLatForLeaflet(props.address.point), {
      icon: markerIcon,
    });
    marker.addTo(map);
  }
});

const makeUrlGoogleMap = (address: Address): string => {
  const params = new URLSearchParams();
  params.append("api", "1");
  if (address.point !== null && address.addressReference !== null) {
    params.append(
      "query",
      `${address.point.coordinates[1]} ${address.point.coordinates[0]}`,
    );
  } else {
    params.append("query", address.lines.join(", "));
  }

  return `https://www.google.com/maps/search/?${params.toString()}`;
};

const makeUrlOsm = (address: Address): string => {
  if (address.point !== null && address.addressReference !== null) {
    const params = new URLSearchParams();
    params.append("mlat", `${address.point.coordinates[1]}`);
    params.append("mlon", `${address.point.coordinates[0]}`);
    const hashParams = new URLSearchParams();
    hashParams.append(
      "map",
      `18/${address.point.coordinates[1]}/${address.point.coordinates[0]}`,
    );

    return `https://www.openstreetmap.org/?${params.toString()}#${hashParams.toString()}`;
  }

  const params = new URLSearchParams();
  params.append("query", address.lines.join(", "));

  return `https://www.openstreetmap.org/search?${params.toString()}`;
};
</script>

<style scoped>
div.address_details_map {
  height: 250px;
}
</style>
