<script setup lang="ts">
import { getSelectedProfile } from '@/api/profile'
import { TransactionApiClient, type TransactionVendor } from '@/api/transaction'
import { onMounted, ref, watch, type Ref } from 'vue'
import { useRoute } from 'vue-router'
import VueSelect, { type Option } from 'vue3-select-component'

const model = defineModel<TransactionVendor | null>({ required: true })

const route = useRoute()
const options: Ref<Option<string>[]> = ref([])
const existingVendors: Ref<TransactionVendor[]> = ref([])
const selectedVendorName: Ref<string | null> = ref(null)

watch(model, (newValue) => {
  if (newValue === null) {
    selectedVendorName.value = null
  } else {
    selectedVendorName.value = newValue.name
  }
})

onMounted(() => {
  const api = new TransactionApiClient(getSelectedProfile(route))
  if (model.value !== null) {
    selectedVendorName.value = model.value?.name
  }
  api.getVendors().then((vendors) => {
    existingVendors.value = vendors
    options.value = vendors.map((v) => {
      return { label: v.name, value: v.name }
    })
  })
})

function onOptionCreated(value: string) {
  const existingVendor = existingVendors.value.find((obj) => obj.name === value)
  if (existingVendor) {
    selectedVendorName.value = existingVendor.name
    model.value = existingVendor
    return
  }
  // Clear out any previously-added custom value from the list of options.
  options.value = options.value.filter((opt) =>
    existingVendors.value.some((v) => v.name === opt.value),
  )
  // Then add the new custom value, select it, and set the model.
  options.value.push({ label: value, value: value })
  selectedVendorName.value = value
  model.value = { id: -1, name: value, description: null }
}

function onOptionSelected() {
  model.value = existingVendors.value.find((v) => v.name === selectedVendorName.value) ?? null
}

function onOptionDeselected() {
  model.value = null
}
</script>
<template>
  <VueSelect
    class="vendor-select"
    v-model="selectedVendorName"
    :options="options"
    placeholder="Select a vendor"
    is-taggable
    @option-created="onOptionCreated"
    @option-selected="onOptionSelected"
    @option-deselected="onOptionDeselected"
  >
    <template #taggable-no-options> Add a new vendor. </template>
  </VueSelect>
</template>
<style lang="css">
.vendor-select {
  --vs-line-height: 1;
}
</style>
