<template>
  <div class="PickPostalCode">
    <vue-multiselect
      id="citySelector"
      @search-change="listenInputSearch"
      ref="citySelector"
      v-model="internalPicked"
      @select="selectCity"
      @remove="remove"
      name=""
      track-by="id"
      label="value"
      :custom-label="transName"
      :placeholder="$t('select_city')"
      :select-label="$t('multiselect.select_label')"
      :deselect-label="$t('multiselect.deselect_label')"
      :selected-label="$t('multiselect.selected_label')"
      :taggable="true"
      :multiple="false"
      :internal-search="false"
      :loading="isLoading"
      :options="cities"
    />
  </div>
</template>

<script lang="js">
import VueMultiselect from "vue-multiselect";
import { searchCities } from "./api";

export default {
  components: {
    VueMultiselect,
  },
  data() {
    return {
      cities: [],
      internalPicked: null,
      isLoading: false,
      abortControllers: [],
    };
  },
  emits: ["pickCity", "removeCity"],
  props: {
    picked: {
      type: Object,
      required: false,
      default: null,
    },
    country: {
      type: Object,
      required: false,
      default: null,
    },
  },
  mounted() {
    if (this.picked !== null) {
      this.internalPicked = this.picked;
      this.cities.push(this.picked);
    }
  },
  methods: {
    transName(value) {
      return value.code && value.name ? `${value.name} (${value.code})` : "";
    },
    selectCity(city) {
      this.$emit("selectCity", city);
    },
    listenInputSearch(query) {
      if (query.length <= 2) {
        return;
      }

      let c = this.abortControllers.pop();

      while (typeof c !== "undefined") {
        c.abort();
        c = this.abortControllers.pop();
      }

      this.isLoading = true;
      let controller = new AbortController();
      this.abortControllers.push(controller);

      searchCities(query, this.country, controller)
        .then((newCities) => {
          this.cities = this.cities.filter((city) => city.id === this.picked);
          newCities.forEach((item) => {
            this.cities.push(item);
          });
          this.isLoading = false;

          return Promise.resolve();
        })
        .catch((error) => {
          console.log(error); //TODO better error handling
          this.isLoading = false;
        });
    },
    remove(item) {
      this.$emit("removeCity", item);
    },
  },
};
</script>
