<template>
  <div class="market-search-bar" :class="props.class">
    <!-- Enhanced Search Input with Features -->
    <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
        ref="searchInputRef"
        :model-value="internalQuery || searchQuery"
        @update:model-value="handleSearchChange"
        @keydown="handleKeydown"
        @focus="handleFocus"
        @blur="handleBlur"
        :placeholder="computedPlaceholder"
        :disabled="disabled"
        :class="['pl-10', showEnhancements ? 'pr-20' : 'pr-10']"
      />

      <!-- Enhanced Features (keyboard hints, clear button) -->
      <div class="absolute inset-y-0 right-0 pr-3 flex items-center gap-2">
        <!-- Keyboard Shortcuts Hint (only for enhanced mode on desktop) -->
        <div v-if="showEnhancements && showKeyboardHints && !internalQuery && !searchQuery && isDesktop" class="text-xs text-muted-foreground flex items-center gap-1">
          <Badge variant="outline" class="px-1 py-0 text-xs">⌘ K</Badge>
        </div>

        <!-- Clear Button -->
        <Button
          v-if="internalQuery || searchQuery"
          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>

    <!-- Enhanced Features Section -->
    <template v-if="showEnhancements">
      <!-- Result Count with Quick Filters -->
      <div v-if="isSearching && showResultCount" class="mt-2 flex items-center justify-between text-sm text-muted-foreground">
        <span>{{ resultCount }} result{{ resultCount === 1 ? '' : 's' }} found</span>

        <!-- Quick Category Filters -->
        <div v-if="searchQuery && topCategories.length > 0" class="flex items-center gap-1">
          <span class="text-xs">In:</span>
          <Button
            v-for="category in topCategories.slice(0, 3)"
            :key="category"
            variant="ghost"
            size="sm"
            @click="filterByCategory(category)"
            class="h-5 px-1 text-xs"
          >
            {{ category }}
          </Button>
        </div>
      </div>

      <!-- Search Suggestions Dropdown -->
      <SearchSuggestions
        :show-suggestions="showSuggestions"
        :show-recent-searches="showRecentSearches"
        :search-query="searchQuery"
        :is-focused="isFocused"
        :suggestions="searchSuggestions"
        :recent-searches="recentSearches"
        @apply-suggestion="applySuggestion"
        @apply-recent="applyRecentSearch"
        @clear-recent="clearRecentSearches"
      />
    </template>

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

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { useFuzzySearch, type FuzzySearchOptions } from '@/composables/useFuzzySearch'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Search, X } from 'lucide-vue-next'
import { useLocalStorage, useBreakpoints, breakpointsTailwind, useDebounceFn } from '@vueuse/core'
import type { Product } from '../types/market'

// Conditional imports for enhanced mode
const SearchSuggestions = ref()
const useSearchKeyboardShortcuts = ref()

interface Props {
  /**
   * The data to search through
   */
  data: Product[]
  /**
   * Configuration options for the fuzzy search
   */
  options?: FuzzySearchOptions<Product>
  /**
   * Placeholder text for the search input
   */
  placeholder?: string
  /**
   * Whether to show enhanced features (suggestions, keyboard shortcuts, etc.)
   */
  showEnhancements?: boolean
  /**
   * Whether to show keyboard hints (only works with enhancements)
   */
  showKeyboardHints?: boolean
  /**
   * Whether to show the result count
   */
  showResultCount?: boolean
  /**
   * Whether to show search suggestions (only works with enhancements)
   */
  showSuggestions?: boolean
  /**
   * Whether to show recent searches (only works with enhancements)
   */
  showRecentSearches?: boolean
  /**
   * Custom class for the search container
   */
  class?: string | string[]
  /**
   * Whether the search input should be disabled
   */
  disabled?: boolean
}

interface Emits {
  (e: 'update:modelValue', value: string): void
  (e: 'search', query: string): void
  (e: 'results', results: Product[]): void
  (e: 'clear'): void
  (e: 'filter-category', category: string): void
}

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

const emit = defineEmits<Emits>()

// Dynamically import enhanced features only when needed
const initializeEnhancements = async () => {
  if (props.showEnhancements) {
    const [suggestionModule, shortcutModule] = await Promise.all([
      import('./SearchSuggestions.vue'),
      import('../composables/useSearchKeyboardShortcuts')
    ])
    SearchSuggestions.value = suggestionModule.default
    useSearchKeyboardShortcuts.value = shortcutModule.useSearchKeyboardShortcuts
  }
}

// Initialize enhancements
initializeEnhancements()

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

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

// Local state
const searchInputRef = ref()
const isFocused = ref(false)

// Enhanced features state (only initialized if showEnhancements is true)
const recentSearches = computed(() =>
  props.showEnhancements ? useLocalStorage<string[]>('market-recent-searches', []) : ref([])
)

// Responsive breakpoints (only for enhanced mode)
const breakpoints = computed(() =>
  props.showEnhancements ? useBreakpoints(breakpointsTailwind) : null
)
const isDesktop = computed(() =>
  props.showEnhancements && breakpoints.value ? breakpoints.value.greaterOrEqual('lg') : ref(false)
)

// Computed placeholder with keyboard shortcut hint
const computedPlaceholder = computed(() => {
  if (props.showEnhancements && props.showKeyboardHints && isDesktop.value?.value) {
    return `${props.placeholder} (⌘K to focus)`
  }
  return props.placeholder
})

// Extract categories from search results for quick filters (enhanced mode only)
const topCategories = computed(() => {
  if (!props.showEnhancements) return []

  const categoryCount = new Map<string, number>()

  filteredItems.value.forEach(product => {
    product.categories?.forEach(category => {
      categoryCount.set(category, (categoryCount.get(category) || 0) + 1)
    })
  })

  return Array.from(categoryCount.entries())
    .sort((a, b) => b[1] - a[1])
    .map(([category]) => category)
})

// Generate search suggestions (enhanced mode only)
const searchSuggestions = computed(() => {
  if (!props.showEnhancements) return []

  const suggestions = new Set<string>()

  // Add popular categories
  const allCategories = new Map<string, number>()
  props.data.forEach(product => {
    product.categories?.forEach(category => {
      allCategories.set(category, (allCategories.get(category) || 0) + 1)
    })
  })

  Array.from(allCategories.entries())
    .sort((a, b) => b[1] - a[1])
    .slice(0, 4)
    .forEach(([category]) => suggestions.add(category))

  // Add popular stall names
  const stallNames = new Map<string, number>()
  props.data.forEach(product => {
    if (product.stallName && product.stallName !== 'Unknown Stall') {
      stallNames.set(product.stallName, (stallNames.get(product.stallName) || 0) + 1)
    }
  })

  Array.from(stallNames.entries())
    .sort((a, b) => b[1] - a[1])
    .slice(0, 2)
    .forEach(([stall]) => suggestions.add(stall))

  return Array.from(suggestions)
})

// Methods
// Internal search query for immediate UI updates
const internalQuery = ref('')

// Debounced search function for performance optimization
const debouncedSearch = useDebounceFn((value: string) => {
  setSearchQuery(value)
  emit('search', value)
  emit('results', filteredItems.value)

  // Add to recent searches when user finishes typing (enhanced mode only)
  if (props.showEnhancements && value.trim() && value.length >= 3) {
    addToRecentSearches(value.trim())
  }
}, 300)

const handleSearchChange = (value: string | number) => {
  const stringValue = String(value)

  // Update internal query immediately for responsive UI
  internalQuery.value = stringValue
  emit('update:modelValue', stringValue)

  // Debounce the actual search computation
  debouncedSearch(stringValue)
}

const handleClear = () => {
  // Clear both internal and actual search queries
  internalQuery.value = ''
  clearSearch()
  emit('update:modelValue', '')
  emit('search', '')
  emit('results', filteredItems.value)
  emit('clear')

  // Focus the input after clearing (enhanced mode only)
  if (props.showEnhancements) {
    focusSearchInput()
  }
}

const handleKeydown = (event: KeyboardEvent) => {
  if (!props.showEnhancements) return

  // Handle basic Escape key for simple mode
  if (event.key === 'Escape') {
    event.preventDefault()
    if (internalQuery.value || searchQuery.value) {
      handleClear()
    }
    return
  }

  // Use enhanced keyboard shortcuts if available
  if (useSearchKeyboardShortcuts.value && handleSearchKeydown) {
    const shouldClear = handleSearchKeydown(event)
    if (shouldClear) {
      if (internalQuery.value || searchQuery.value) {
        handleClear()
      } else {
        blurSearchInput()
      }
    }
  }
}

const filterByCategory = (category: string) => {
  emit('filter-category', category)
  internalQuery.value = category
  setSearchQuery(category)
}

const applySuggestion = (suggestion: string) => {
  internalQuery.value = suggestion
  setSearchQuery(suggestion)
  addToRecentSearches(suggestion)
}

const applyRecentSearch = (recent: string) => {
  internalQuery.value = recent
  setSearchQuery(recent)
}

const addToRecentSearches = (query: string) => {
  if (!props.showEnhancements) return

  const searches = recentSearches.value.value.filter(s => s !== query)
  searches.unshift(query)
  recentSearches.value.value = searches.slice(0, 10) // Keep only 10 recent searches
}

const clearRecentSearches = () => {
  if (props.showEnhancements) {
    recentSearches.value.value = []
  }
}

// Focus handling
const handleFocus = () => {
  isFocused.value = true
}

const handleBlur = () => {
  // Delay hiding to allow clicking on suggestions
  setTimeout(() => {
    isFocused.value = false
  }, 200)
}

// Enhanced mode methods (initialized conditionally)
let focusSearchInput = () => {}
let blurSearchInput = () => {}
let handleSearchKeydown = (_event: KeyboardEvent) => false

// Initialize keyboard shortcuts for enhanced mode
watch(() => props.showEnhancements, async (showEnhancements) => {
  if (showEnhancements && useSearchKeyboardShortcuts.value) {
    const shortcuts = useSearchKeyboardShortcuts.value(searchInputRef)
    focusSearchInput = shortcuts.focusSearchInput
    blurSearchInput = shortcuts.blurSearchInput
    handleSearchKeydown = shortcuts.handleSearchKeydown
  }
}, { immediate: true })

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

<style scoped>
.market-search-bar {
  @apply w-full relative;
}
</style>