<template>
  <v-menu location="bottom left">
    <template #activator="bind">
      <div v-bind="bind.props">
        <v-text-field
          v-model="place.search.params[ props.searchBy ]"
          :label="props.label"
          append-inner-icon="mdi-map-marker"
          :loading="place.search.loading || map.markerDragendHandlerTimeout"
          style="min-width:300px; max-width:100vw;"
          @keyup="place.search.load()"
        ></v-text-field>
      </div>
    </template>

    <v-card width="auto" style="min-width:400px; max-width:100vw;">
      <!-- <l-map
        ref="mapRef"
        style="height:200px;"
        :options="map.options"
      >
        <l-tile-layer />
        <l-marker
          :center="map.options.center"
          :options="{ draggable: true }"
          @dragend="map.markerDragendHandler($event)"
        ></l-marker>
      </l-map> -->
      
      <v-list
        style="max-height:250px; overflow:auto;"
      >
        <v-list-subheader v-if="place.search.params[ props.searchBy ]">
          Results for <q>{{ place.search.params[ props.searchBy ] }}</q>:
        </v-list-subheader>
        <v-list-item
          class="text-disabled"
          v-if="!place.search.loading && place.search.data.length==0"
        >
          No results
        </v-list-item>
        <v-list-item
          v-for="p in place.search.data.filter(p => p.city)"
          :key="p.id"
          @click="map.selectPlace(p)"
        >
          {{ p.name }}
          <template #prepend>
            <v-img :src="p.flag" width="20" class="me-4" />
          </template>
        </v-list-item>
      </v-list>
      <v-btn block @click="map.clear();">
        <span class="me-2">Clear</span>
        <v-icon size="15">mdi-close</v-icon>
      </v-btn>
    </v-card>
  </v-menu>
</template>

<script setup>
  const { ref, defineEmits, onMounted } = Vue;
  // import { LMap, LTileLayer, LMarker, LMapObj } from '@/components/leaflet';

  const emit = defineEmits(['change']);

  const props = defineProps({
    label: {
      type: String,
      default: 'Destination',
    },
    search: {
      type: String,
      default: '',
    },
    searchBy: {
      type: String,
      default: 'q', // q, amenity, street, city, county, state, country, postalcode
    },
    params: {
      type: Object,
      default: () => ({}),
    },
  });
  
  const place = usePlace();

  const map = ref({
    place: false,
    options: {
      zoom: 10,
      // minZoom: 10,
      // maxZoom: 10,
      center: [-35.281865, 149.128620],
      zoomControl: false,
    },
    selectPlace(addr) {
      this.place = addr;
      this.options.center = [
        parseFloat(addr.lat),
        parseFloat(addr.lng),
      ];
      place.value.search.params[ props.searchBy ] = addr[ props.searchBy ];
      emit('change', addr);
    },
    markerDragendHandlerTimeout: false,
    async markerDragendHandler({ coords }) {
      this.options.center = [
        parseFloat(coords.lat),
        parseFloat(coords.lng),
      ];
      if (this.markerDragendHandlerTimeout) {
        clearTimeout(this.markerDragendHandlerTimeout);
        this.markerDragendHandlerTimeout = false;
      }
      this.markerDragendHandlerTimeout = setTimeout(async () => {
        try {
          const { data } = await axios.get(`https://nominatim.openstreetmap.org/reverse?format=json&addressdetails=1&extratags=1&namedetails=1&limit=10&lat=${coords.lat}&lon=${coords.lng}`);
          const addr = place.value.search.placeParse(data);
          this.selectPlace(addr);
        } catch(err) {
          console.error(err);
        }
        this.markerDragendHandlerTimeout = false;
      }, 1000);
    },
    initialLoad: async () => {
      let params = {
        format: 'json',
        addressdetails: 1,
        extratags: 1,
        limit: 1,
      };
      params[ props.searchBy ] = props.params[ props.searchBy ];
      const { data } = await axios.get('https://nominatim.openstreetmap.org/search.php', { params });
      if (data[0]) {
        let addr = place.value.search.placeParse(data[0]);
        map.value.selectPlace(addr);
      }
    },
    clear() {
      const addr = place.value.search.placeParse({});
      map.value.selectPlace(addr);
    },
  });

  onMounted(() => {
    // place.value.search.load();
    map.value.initialLoad();
  });
</script>