const MAX_DISTANCE = 1000

export const fuzzySearch = (query: string, text: string): number => {
  if (!query) return 0
  
  const queryLower = query.toLowerCase()
  const textLower = text.toLowerCase()
  
  if (textLower.startsWith(queryLower)) {
    return 1 - query.length / text.length
  }
  
  let score = 0
  let queryIndex = 0
  
  for (let i = 0; i < textLower.length && queryIndex < queryLower.length; i++) {
    if (textLower[i] === queryLower[queryIndex]) {
      score++
      queryIndex++
    }
  }
  
  if (score === 0) return 0
  
  const matchRatio = score / query.length
  const positionBonus = queryIndex === query.length ? 0.2 : 0
  const lengthPenalty = Math.min(1, text.length / MAX_DISTANCE)
  
  return (matchRatio * 0.7 + positionBonus) * lengthPenalty
}

export const fuzzyFilter = <T extends { name: string; type?: string }>(
  items: T[],
  query: string,
  typeFilter?: string
): T[] => {
  if (!query && !typeFilter) return items
  
  return items
    .map((item) => ({
      item,
      score: fuzzySearch(query, item.name),
    }))
    .filter(
      ({ item, score }) =>
        score > 0.3 && (!typeFilter || typeFilter === 'all' || item.type === typeFilter)
    )
    .sort((a, b) => b.score - a.score)
    .map(({ item }) => item)
}
