<!--
Liste déroulante avec autocompletion (les données sont issues
d'une api)

@see https://vuetifyjs.com/en/components/autocompletes/#usage
-->
<template>
  <main>
    <UiInputAutocomplete
      :field="field"
      :label="label"
      :data="remoteData ? remoteData : data"
      :items="items"
      :is-loading="isLoading"
      :item-text="itemText"
      :slot-text="slotText"
      :item-value="itemValue"
      :multiple="multiple"
      :chips="chips"
      prepend-icon="mdi-magnify"
      :return-object="returnObject"
      :no-filter="noFilter"
      @research="search"
      @update="$emit('update', $event, field)"
    />
  </main>
</template>

<script setup lang="ts">
import { ref, toRefs, watch } from 'vue'
import type { Ref } from 'vue'
import { useFetch } from '#app'
import UrlUtils from '~/services/utils/urlUtils'

const props = defineProps({
  label: {
    type: String,
    required: false,
    default: null,
  },
  field: {
    type: String,
    required: false,
    default: null,
  },
  searchFunction: {
    type: Function as PropType<
      (research: string, field?: string) => Promise<Array<unknown>>
    >,
    required: true,
  },
  data: {
    type: [String, Number, Object, Array],
    required: false,
    default: null,
  },
  remoteUri: {
    type: [Array],
    required: false,
    default: null,
  },
  remoteUrl: {
    type: String,
    required: false,
    default: null,
  },
  readonly: {
    type: Boolean,
    required: false,
  },
  itemValue: {
    type: String,
    default: 'id',
  },
  itemTitle: {
    type: Array,
    required: true,
  },
  slotText: {
    type: Array,
    required: false,
    default: () => [],
  },
  returnObject: {
    type: Boolean,
    default: false,
  },
  noFilter: {
    type: Boolean,
    default: false,
  },
  multiple: {
    type: Boolean,
    default: false,
  },
  chips: {
    type: Boolean,
    default: false,
  },
})

const emit = defineEmits(['update'])

const { data } = toRefs(props)
const items = ref([])
const remoteData: Ref<Array<string> | null> = ref(null)
const isLoading = ref(false)

if (props.data) {
  items.value = props.multiple ? (data.value ?? []) : [data.value]
} else if (props.remoteUri) {
  const ids: Array<string | number> = []

  for (const uri of props.remoteUri) {
    ids.push(UrlUtils.extractIdFromUri(uri as string))
  }

  const options: FetchOptions = {
    method: 'GET',
    query: { key: 'id', value: ids.join(',') },
  }

  useFetch(async () => {
    isLoading.value = true

    const r: { data: Array<string> } = await $fetch(props.remoteUrl, options)

    isLoading.value = false
    remoteData.value = r.data
    items.value = r.data
  })
}

const search = async (research: string) => {
  isLoading.value = true
  const func = props.searchFunction
  items.value = items.value.concat(await func(research, props.field))
  isLoading.value = false
}

const unwatch = watch(data, (d) => {
  items.value = props.multiple ? d : [d]
})

onUnmounted(() => {
  unwatch()
})
</script>
