import { ref } from 'vue'
import api from '../api'

/**
 * "Did you mean" for a search that found nothing.
 *
 * ONE composable for every list in the product. Thirty routes take a search
 * parameter across a dozen files, so carrying a suggestion in each of their
 * responses would be a large change now and a thing every future plugin has to
 * remember. Instead a page that renders no rows asks for a spelling, and a page
 * that has not adopted this shows nothing - exactly what it showed before.
 *
 * Usage in a list view:
 *
 *     const { suggestion, checkSuggestion, clearSuggestion } = useSearchSuggestion()
 *     // after a fetch:
 *     items.value.length ? clearSuggestion() : checkSuggestion(searchTerm.value)
 *
 * and in the template, beside the empty state:
 *
 *     <SearchSuggestion :suggestion="suggestion" @pick="applySuggestion" />
 */
export function useSearchSuggestion() {
  const suggestion = ref(null)
  // Guards a slow answer arriving after a newer search has already been typed,
  // which would offer a spelling for a query nobody is looking at any more.
  let latest = 0

  function clearSuggestion() {
    suggestion.value = null
    latest += 1
  }

  async function checkSuggestion(query) {
    const term = (query || '').trim()
    if (term.length < 2) {
      clearSuggestion()
      return
    }
    const ticket = ++latest
    try {
      const response = await api.get('/search/suggest', { params: { q: term } })
      if (ticket !== latest) return
      const offered = response.data?.data?.suggestion || null
      // Never offer back what was typed: a suggestion identical to the query
      // reads as a broken feature.
      suggestion.value = offered && offered !== term.toLowerCase() ? offered : null
    } catch (err) {
      // A search that found nothing is already the answer. Failing to improve
      // on it is not worth an error in front of anyone.
      if (ticket === latest) suggestion.value = null
    }
  }

  return { suggestion, checkSuggestion, clearSuggestion }
}
