<template>
  <q-select
    ref="select"
    v-bind="$attrs"
    v-on="$listeners"
    :value="value"
    :options="options"
    @filter="filter"
    use-input
    :input-debounce="200"
    fill-input
    hide-selected
    hide-dropdown-icon
    class="inline ui-search-select"
    :class="{ 'ui-search-select--edited': value }"
    dense
    dark
    color="white"
    bg-color="transparent"
    :options-dark="false"
    options-selected-class="text-primary"
  >
    <template #prepend>
      <q-icon name="las la-search" />
    </template>

    <template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope">
      <slot :name="slot" v-bind="scope" />
    </template>
  </q-select>
</template>

<script lang="ts">
import { Component, Prop, Ref, Vue, Watch } from 'vue-property-decorator'
import { QIcon, QSelect } from 'quasar'

@Component({ inheritAttrs: false, components: { QSelect, QIcon } })
export default class UiSearchSelect<T> extends Vue {
  @Prop()
  value?: T

  @Prop({ type: Function, required: true })
  searchCb!: (query: string) => Promise<T[]>

  @Prop()
  width?: string

  @Ref() readonly select!: Vue

  options: T[] = []

  async filter(query: string, done: (callback: () => void) => void) {
    // query === '' если инпут пустой или инпут получил фокус
    if (query === '') {
      return done(() => {})
    }

    const products = await this.searchCb(query)

    done(() => {
      this.options = products
    })
  }

  @Watch('width')
  updateExpandedWidth() {
    ;(this.select.$el as HTMLElement).style.setProperty(
      '--ui-search-select--expanded-width',
      this.width ?? ''
    )
  }

  mounted() {
    this.updateExpandedWidth()
  }
}
</script>
