<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>
