<template>
  <DefaultSelect
    v-model="selectedCity"
    v-bind="$attrs"
    use-input
    hide-selected
    fill-input
    clearable
    :options="cityOptions"
    :label
    :loading
    :placeholder
    @filter="filterFn"
  >
    <template #no-option>
      <q-item>
        <q-item-section class="text-grey">
          {{ $t("http.errors.no_records_found") }}
        </q-item-section>
      </q-item>
    </template>
  </DefaultSelect>
</template>

<script setup>
import { getCities } from "src/api/city";
import { ref, watch } from "vue";
import { normalizeString } from "src/helpers/utils";
import { useI18n } from "vue-i18n";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";

const emit = defineEmits(["selectedStateId"]);

const { state, label, placeholder } = defineProps({
  state: {
    type: Object,
    required: false,
    default: null,
  },
  label: {
    type: String,
    default: () => useI18n().t("ui.navigation.city"),
  },
  placeholder: {
    type: String,
    default: () =>
      useI18n().t("common.actions.search") +
      " " +
      useI18n().t("ui.navigation.city"),
  },
});

const selectedCity = defineModel({ type: Object });

const loading = ref(false);
const baseOptions = ref([]);
const cityOptions = ref([]);

const ensureOnlyPossibleOptions = (state_id) => {
  cityOptions.value = state_id
    ? baseOptions.value.filter((c) => c.state_id === state_id)
    : baseOptions.value;
};

const filterFn = async (val, update) => {
  if (baseOptions.value.length === 0) {
    loading.value = true;
    try {
      const data = await getCities();
      baseOptions.value = data.map((c) => ({
        label: c.name,
        value: c.id,
        state_id: c.state_id,
      }));
    } catch (e) {
      console.error(e);
    } finally {
      loading.value = false;
    }
  }
  ensureOnlyPossibleOptions(state?.value);
  const needle = normalizeString(val);
  if (needle) {
    cityOptions.value = cityOptions.value.filter((v) =>
      normalizeString(v.label).includes(needle),
    );
  }
  update();
};

const selectCityByName = (name) => {
  if (selectedCity.value?.label === name) return;
  selectedCity.value = baseOptions.value.find((c) => c.label === name);
};

const selectCityById = (id) => {
  if (selectedCity.value?.value === id) return;
  selectedCity.value = baseOptions.value.find((c) => c.value === id);
};

watch(
  () => state,
  (value, oldValue) => {
    if (!oldValue) return;
    if (value?.value != oldValue?.value && value?.value != selectedCity.value?.state_id) {
      selectedCity.value = null;
    }
    if (value && baseOptions.value.length > 0) {
      ensureOnlyPossibleOptions(value.value);
    }
  },
);

watch(selectedCity, () => {
  if (selectedCity.value?.state_id) {
    emit("selectedStateId", selectedCity.value.state_id);
  }
});

defineExpose({
  selectCityByName,
  selectCityById,
});
</script>
