<script setup lang="ts">
import { computed, watch } from 'vue'
import { useFuzzySearch, type FuzzySearchOptions } from '@/composables/useFuzzySearch'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { Search, X } from 'lucide-vue-next'

interface Props<T = any> {
  /**
   * The data to search through
   */
  data: T[]
  /**
   * Configuration options for the fuzzy search
   */
  options?: FuzzySearchOptions<T>
  /**
   * Placeholder text for the search input
   */
  placeholder?: string
  /**
   * Whether to show a clear button
   */
  showClearButton?: boolean
  /**
   * Whether to show the result count
   */
  showResultCount?: boolean
  /**
   * Custom class for the search container
   */
  class?: string
  /**
   * Whether the search input should be disabled
   */
  disabled?: boolean
}

interface Emits<T = any> {
  (e: 'update:modelValue', value: string): void
  (e: 'search', query: string): void
  (e: 'results', results: T[]): void
  (e: 'clear'): void
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: 'Search...',
  showClearButton: true,
  showResultCount: true,
  disabled: false
})

const emit = defineEmits<Emits>()

// Create reactive data ref for the composable
const dataRef = computed(() => props.data)

// Use the fuzzy search composable
const {
  searchQuery,
  results,
  filteredItems,
  isSearching,
  resultCount,
  clearSearch,
  setSearchQuery
} = useFuzzySearch(dataRef, props.options)

// Emit events when search changes
const handleSearchChange = (value: string | number) => {
  const stringValue = String(value)
  setSearchQuery(stringValue)
  emit('update:modelValue', stringValue)
  emit('search', stringValue)
  emit('results', filteredItems.value)
}

const handleClear = () => {
  clearSearch()
  emit('update:modelValue', '')
  emit('search', '')
  emit('results', filteredItems.value)
  emit('clear')
}

// Watch for changes in filtered items and emit results
watch(filteredItems, (items) => {
  emit('results', items)
}, { immediate: true })
</script>

<template>
  <div :class="['fuzzy-search', class]">
    <!-- Search Input -->
    <div class="relative">
      <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
        <Search class="h-4 w-4 text-muted-foreground" />
      </div>
      
      <Input
        :model-value="searchQuery"
        @update:model-value="handleSearchChange"
        :placeholder="placeholder"
        :disabled="disabled"
        class="pl-10 pr-10"
      />
      
      <!-- Clear Button -->
      <div v-if="showClearButton && searchQuery" class="absolute inset-y-0 right-0 pr-3 flex items-center">
        <Button
          variant="ghost"
          size="sm"
          @click="handleClear"
          class="h-6 w-6 p-0 hover:bg-muted"
        >
          <X class="h-3 w-3" />
          <span class="sr-only">Clear search</span>
        </Button>
      </div>
    </div>

    <!-- Result Count -->
    <div v-if="showResultCount && isSearching" class="mt-2 text-sm text-muted-foreground">
      {{ resultCount }} result{{ resultCount === 1 ? '' : 's' }} found
    </div>
  </div>
</template>

<style scoped>
.fuzzy-search {
  @apply w-full;
}
</style> 