<!--
Liste déroulante avec autocompletion

@see https://vuetifyjs.com/en/components/autocompletes/#usage
-->

<template>
  <main>
    <v-autocomplete
      autocomplete="search"
      :value="data"
      :items="itemsToDisplayed"
      :label="$t(label)"
      item-text="itemTextDisplay"
      :item-value="itemValue"
      :no-data-text="$t('autocomplete_research')"
      :no-filter="noFilter"
      auto-select-first
      :multiple="multiple"
      :loading="isLoading"
      :return-object="returnObject"
      :search-input.sync="search"
      :prepend-icon="prependIcon"
      :error="error"
      @input="onChange($event)"
    >
      <template v-if="slotText" v-slot:item="data">
        <v-list-item-content v-text="data.item.slotTextDisplay"></v-list-item-content>
      </template>
    </v-autocomplete>
  </main>
</template>

<script lang="ts">
import { computed, defineComponent, ComputedRef, Ref, ref, watch, onUnmounted } from '@nuxtjs/composition-api'
import { AnyJson } from '~/types/interfaces'
import * as _ from 'lodash'
import {$objectProperties} from "~/services/utils/objectProperties";
import {$useError} from "~/use/form/useError";

export default defineComponent({
  props: {
    label: {
      type: String,
      required: false,
      default: null
    },
    field: {
      type: String,
      required: false,
      default: null
    },
    data: {
      type: [String, Number, Object],
      required: false,
      default: null
    },
    items: {
      type: Array,
      required: false,
      default: () => []
    },
    readonly: {
      type: Boolean,
      required: false
    },
    itemValue: {
      type: String,
      default: 'id'
    },
    itemText: {
      type: Array,
      required: true
    },
    slotText: {
      type: Array,
      required: false,
      default: null
    },
    returnObject: {
      type: Boolean,
      default: false
    },
    multiple: {
      type: Boolean,
      default: false
    },
    isLoading: {
      type: Boolean,
      default: false
    },
    noFilter: {
      type: Boolean,
      default: false
    },
    prependIcon: {
      type: String
    },
  },
  setup (props, { emit }) {
    const search:Ref<string|null> = ref(null)
    const {error, onChange} = $useError(props.field, emit)

    // On reconstruit les items à afficher car le text de l'Item doit être construit par rapport au itemText passé en props
    const itemsToDisplayed: ComputedRef<Array<AnyJson>> = computed(() => {
      return props.items.map((item: any) => {
        const slotTextDisplay: Array<string> = []
        const itemTextDisplay: Array<string> = []

        if(item){
          item = $objectProperties.cloneAndFlatten(item)

          //Si on souhaite avoir un texte différent dans les propositions que dans la sélection finale de select
          if(props.slotText){
            for (const text of props.slotText) {
              slotTextDisplay.push(item[text as string])
            }
          }

          for (const text of props.itemText) {
            itemTextDisplay.push(item[text as string])
          }
        }

        //On reconstruit l'objet
        return Object.assign({}, item, { itemTextDisplay: itemTextDisplay.join(' '), slotTextDisplay: slotTextDisplay.join(' ') })
      })
    })

    const unwatch = watch(search, _.debounce(async (newResearch, oldResearch) => {
      if(newResearch !== oldResearch && oldResearch !== null)
        emit('research', newResearch)
    }, 500))

    onUnmounted(() => {
      unwatch()
    })

    return {
      label_field: props.label ?? props.field,
      itemsToDisplayed,
      search,
      error,
      onChange
    }
  }
})
</script>
