<script setup>
import { h, onBeforeUnmount, onMounted, reactive, ref } from "vue";
import { BFormInput, BInputGroup, BButton, useModal } from "bootstrap-vue-next";
import { useNuxtApp } from "#imports";
import FormatIcon from "../format/FormatIcon.vue";
import ModalAddress from "../modal/ModalAddress.vue";
const ADDRESS_FORMAT = {
  city: ["locality", "administrative_area_level_2"],
  code: ["postal_code"],
  country: ["country"],
  locality: ["sublocality", "sublocality_level_1", "political"],
  number: ["street_number"],
  state: ["administrative_area_level_1"],
  street: ["route"]
};
const emit = defineEmits(["search", "error"]);
const props = defineProps({
  mode: { type: String, default: "geocode" },
  countries: { type: Array, default: () => [] },
  placeholder: { type: String, default: "Search address" },
  disabled: { type: Boolean, default: false }
});
const model = defineModel({ type: String, default: () => "" });
const address = reactive({
  city: "",
  code: "",
  country: "",
  latitude: 0,
  line1: "",
  line2: "",
  locality: "",
  longitude: 0,
  name: "",
  number: "",
  state: "",
  street: ""
});
const input = ref();
let placeChangedListener = null;
function setAddress(items) {
  for (const item of items) {
    const type = item.types[0];
    if (!type) continue;
    for (const key of Object.keys(ADDRESS_FORMAT)) {
      if (ADDRESS_FORMAT[key].includes(type)) {
        address[key] = item.short_name;
        break;
      }
    }
  }
  emit("search", { ...address });
}
function getInputElement() {
  return input.value?.$el ?? null;
}
onMounted(() => {
  const { $gmap } = useNuxtApp();
  const inputElement = getInputElement();
  if (!inputElement) return;
  inputElement.value = model.value;
  const ac = new $gmap.places.Autocomplete(inputElement, {
    componentRestrictions: props.countries.length ? { country: props.countries } : void 0,
    types: [props.mode]
  });
  placeChangedListener = ac.addListener("place_changed", () => {
    const place = ac.getPlace();
    if (!place.geometry) {
      return emit("error", place);
    }
    const { lat, lng } = place.geometry.location;
    address.line1 = place.name ?? "";
    address.latitude = lat();
    address.longitude = lng();
    setAddress(place.address_components ?? []);
    model.value = place.formatted_address;
    address.name = model.value;
  });
});
onBeforeUnmount(() => {
  placeChangedListener?.remove();
  placeChangedListener = null;
});
const { create: createModal } = useModal();
async function openAddressModal() {
  const editedAddress = reactive({ ...address });
  const result = await createModal({
    cancelTitle: "Cancelar",
    okTitle: "Guardar",
    size: "lg",
    slots: {
      default: () => h(ModalAddress, {
        address: editedAddress,
        "onUpdate:address": (value) => Object.assign(editedAddress, value)
      })
    },
    title: "Editar direcci\xF3n"
  }).show();
  if (result.ok) {
    Object.assign(address, editedAddress);
    emit("search", { ...address });
  }
}
</script>

<template>
  <BInputGroup>
    <template #append>
      <BButton variant="light" class="border px-3" @click="openAddressModal()">
        <FormatIcon name="map-marker-alt" />
      </BButton>
    </template>

    <BFormInput ref="input" :model-value="model" v-bind="{ ...props, $attrs }" autocomplete="one-time-code" />
  </BInputGroup>
</template>
