<template>
  <div class="map-container">
    <v-skeleton-loader type="image" v-if="pending"></v-skeleton-loader>

    <LMap
      v-show="!pending"
      style="height: 350px"
      :zoom="zoom"
      :center="position"
      :use-global-leaflet="false"
    >

      <LTileLayer
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        attribution="&amp;copy; <a href=&quot;https://www.openstreetmap.org/&quot;>OpenStreetMap</a> contributors"
        layer-type="base"
        name="OpenStreetMap"
      />

      <LMarker
        :lat-lng="position"
        @update:latLng="onPositionUpdate($event)"
        :draggable="!readonly"
         />
    </LMap>

    <v-btn
      prepend-icon="fas fa-location-dot"
      class="mt-3"
      v-if="searchButton && !readonly"
      @click="search()"
    >
      {{$t('search_gps_button')}}
    </v-btn>

    <div v-if="!pending && gpsResponses.length > 0">
      <div v-for="(gpsResponse, key) in gpsResponses" class="address_choices" @click="addressChoice(key)">
        {{gpsResponse['displayName']}}
        <v-btn
          prepend-icon="fas fa-map-location"
          @click="addressChoice(key)"
        >Choisir</v-btn>
      </div>
    </div>

  </div>
</template>

<script setup lang="ts">

import 'leaflet/dist/leaflet.css'
import { LMap, LTileLayer, LMarker } from '@vue-leaflet/vue-leaflet'
import {type ComputedRef, defineProps, type PropType} from 'vue'
import {LatLng, type PointTuple} from 'leaflet'
import {useAp2iRequestService} from "~/composables/data/useAp2iRequestService";
import UrlUtils from "~/services/utils/urlUtils";
import type {AnyJson, CollectionResponsePromise} from "~/types/data";
import Country from "~/models/Core/Country";
import {useEntityManager} from "~/composables/data/useEntityManager";

const props = defineProps({
  latitude: {
    type: Number as PropType<number | null>,
    required: true,
  },
  longitude: {
    type: Number as PropType<number | null>,
    required: true,
  },
  streetAddress:{
    type: String as PropType<string | null>,
    required: false
  },
  streetAddressSecond:{
    type: String as PropType<string | null>,
    required: false
  },
  streetAddressThird:{
    type: String as PropType<string | null>,
    required: false
  },
  postalCode:{
    type: String as PropType<string | null>,
    required: false
  },
  addressCity:{
    type: String as PropType<string | null>,
    required: false
  },
  addressCountryId:{
    type: Number as PropType<number | null>,
    required: false
  },
  searchButton:{
    type: Boolean,
    required: false,
    default: false
  },
  readonly: {
    type: Boolean,
    required: false,
    default: false,
  },
})

const FRANCE_LATTITUDE = 46.603354
const FRANCE_LONGITUDE = 1.888334
const {apiRequestService, pending} = useAp2iRequestService()
const { em } = useEntityManager()

const position:ComputedRef<PointTuple> = computed(()=>{
  return [props.latitude || FRANCE_LATTITUDE, props.longitude || FRANCE_LONGITUDE]
})

const zoom = computed({
  get() {
    return props.latitude && props.latitude != FRANCE_LATTITUDE ? 12 : 5
  },
  set(newValue: string) {
    zoom.value = newValue
  }
})

const emit = defineEmits(['update:latitude', 'update:longitude'])

const onPositionUpdate = (event: LatLng):void => {
  emit('update:latitude', event.lat)
  emit('update:longitude', event.lng)
}

const gpsResponses:Ref<Array<AnyJson>> = ref([])
const search = async () => {
  gpsResponses.value = []
  const baseUrl = UrlUtils.join('api', 'gps-coordinate-searching')
  const query:AnyJson = {
    'streetAddress': props.streetAddress,
    'streetAddressSecond': props.streetAddressSecond,
    'streetAddressThird': props.streetAddressThird,
    'cp': props.postalCode,
    'city': props.addressCity
  }

  if(props.addressCountryId){
    const country:Country = em.find(Country, props.addressCountryId)
    query['country'] = country?.name
  }

  const url = UrlUtils.addQuery(baseUrl, query)
  const responses:CollectionResponsePromise = await apiRequestService.get(url)

  if(responses['member'].length > 0){
    onPositionUpdate(new LatLng(responses['member'][0]['latitude'], responses['member'][0]['longitude']))
    if(responses['member'].length > 1){
      zoom.value = 6
      gpsResponses.value = responses['member']
    }else{
      zoom.value = 12
    }
  }
}

const addressChoice = (key:number):void => {
  zoom.value = 12
  onPositionUpdate(new LatLng(gpsResponses.value[key]['latitude'] as number, gpsResponses.value[key]['longitude']  as number))
}

</script>

<style scoped lang="scss">
.address_choices {
  cursor: pointer;
  width: 60%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 1rem;
  border-radius: 0.5rem;
  margin-top: 0.5rem;
  background-color: #f9f9f9;
  transition: background-color 0.2s ease;

  &:hover {
    background-color: #eef3ff;
  }

  .v-btn {
    flex-shrink: 0;
  }
}

:deep(.v-skeleton-loader__image) {
  height: 350px;
}
:deep(.map_wrap) {
  height: 350px;
}
</style>
