<template>
  <div class="space-y-1">
    <SearchSelect
      :model-value="modelValue ?? undefined"
      :options="productOptions"
      :loading="loading"
      :placeholder="placeholder"
      :empty-text="emptyText"
      size="sm"
      option-value="id"
      :option-label="formatLabel"
      :disabled="disabled"
      server-search
      @update:modelValue="updateValue"
      @search="handleSearch"
    >
      <template #option-description="{ option }">
        <span class="text-xs text-base-content/60">
          {{ formatDescription(option) }}
        </span>
      </template>
    </SearchSelect>
    <p v-if="helperText" class="text-xs text-base-content/60">
      {{ helperText }}
    </p>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import SearchSelect from '~/components/common/SearchSelect.vue'
import { useProducts } from '~/composables/useProducts'

const props = withDefaults(
  defineProps<{
    modelValue?: string | null
    placeholder?: string
    emptyText?: string
    helperText?: string
    disabled?: boolean
    typeProductId?: string | null
  }>(),
  {
    modelValue: '',
    placeholder: 'Sélectionner un produit…',
    emptyText: 'Aucun produit disponible',
    helperText: '',
    disabled: false,
    typeProductId: null,
  },
)

const emit = defineEmits<{
  (e: 'update:modelValue', value: string | null): void
}>()

const { loading: globalLoading, loadProducts } = useProducts()

const localProducts = ref<any[]>([])
const localLoading = ref(false)
const loading = computed(() => localLoading.value || globalLoading.value)

const productOptions = computed(() => localProducts.value)

const loadFilteredProducts = async (search = '') => {
  if (!props.typeProductId) return
  localLoading.value = true
  try {
    const result = await loadProducts({ typeProductId: props.typeProductId, search, itemsPerPage: 200, force: true })
    if (result.success && result.data?.items) {
      localProducts.value = result.data.items
    }
  }
  catch (error: unknown) {
    console.error('Erreur lors du chargement des produits:', error)
  }
  finally {
    localLoading.value = false
  }
}

let searchDebounce: ReturnType<typeof setTimeout> | null = null
const handleSearch = (term: string) => {
  if (searchDebounce) clearTimeout(searchDebounce)
  searchDebounce = setTimeout(() => loadFilteredProducts(term.trim()), 300)
}

onMounted(() => {
  loadFilteredProducts()
})

watch(
  () => props.typeProductId,
  () => {
    loadFilteredProducts()
  },
)

const updateValue = (value: string | number | null | undefined) => {
  if (value === undefined || value === null || value === '') {
    emit('update:modelValue', null)
    return
  }
  emit('update:modelValue', String(value))
}

const formatLabel = (option: any) => {
  if (!option) return ''
  const name = option.name || 'Produit'
  return option.reference ? `${name} — ${option.reference}` : name
}

const formatDescription = (option: any) => {
  const parts: string[] = []
  const typeName = option?.typeProduct?.name
  if (typeName) {
    parts.push(typeName)
  }
  if (option?.reference) {
    parts.push(`Ref. ${option.reference}`)
  }
  if (option?.supplierPrice !== undefined && option.supplierPrice !== null) {
    const price = Number(option.supplierPrice)
    if (!Number.isNaN(price)) {
      parts.push(`${price.toFixed(2)} €`)
    }
  }
  return parts.length ? parts.join(' • ') : 'Sans référence'
}
</script>
