import Fuse from "fuse.js"

import type { AutoCompleteLocation } from "../schema"

type SearchableAutoCompleteLocation = AutoCompleteLocation & {
  nameTokens: string[]
  destinationTokens: string[]
}
type SearchableKey = keyof SearchableAutoCompleteLocation

const fuseConfig = new Fuse([] as SearchableAutoCompleteLocation[], {
  minMatchCharLength: 2,
  isCaseSensitive: false,
  ignoreDiacritics: true,
  includeMatches: true,
  includeScore: true,
  threshold: 0.2,
  keys: [
    {
      name: "nameTokens" satisfies SearchableKey,
      weight: 3,
    },
    {
      name: "destinationTokens" satisfies SearchableKey,
      weight: 2,
    },
    {
      name: "searchTokens" satisfies SearchableKey,
      weight: 1,
    },
  ],
})

export function filterAutoCompleteLocations<T extends AutoCompleteLocation>(
  locations: T[],
  query: string
) {
  const searchable = locations.map((x) => ({
    ...x,
    nameTokens: extractTokens(x.name),
    destinationTokens: extractTokens(x.destination),
  }))
  fuseConfig.setCollection(searchable)

  const searchResults = fuseConfig.search(query, { limit: 50 })

  return searchResults.map(
    (x) =>
      ({
        id: x.item.id,
        name: x.item.name,
        cityIdentifier: x.item.cityIdentifier,
        destination: x.item.destination,
        searchTokens: x.item.searchTokens,
        type: x.item.type,
        url: x.item.url,
      }) satisfies AutoCompleteLocation
  )
}

function extractTokens(value: string): string[] {
  const cleaned = value?.toLowerCase().replaceAll("scandic", "").trim() ?? ""
  const output = [...new Set([cleaned, ...cleaned.split(" ")])]

  return output
}
