import type { CommandPaletteOption } from './types'
import { computeMatchHighlightRanges, scoreMatch } from './match'

export { clamp } from '../../utils/math'

export type FilteredOption = Readonly<{
  idx: number
  opt: CommandPaletteOption
  score: number
  labelHighlightRanges: readonly Readonly<{ start: number; end: number }>[]
  detailHighlightRanges: readonly Readonly<{ start: number; end: number }>[]
}>

export function filterCommandPaletteOptions(
  options: readonly CommandPaletteOption[],
  query: string,
): FilteredOption[] {
  const q = query.trim()
  const out: Array<{
    idx: number
    opt: CommandPaletteOption
    score: number
    labelHighlightRanges: readonly Readonly<{ start: number; end: number }>[]
    detailHighlightRanges: readonly Readonly<{ start: number; end: number }>[]
  }> = []
  for (let i = 0; i < options.length; i++) {
    const opt = options[i]!
    if (opt.kind === 'separator') {
      if (q) continue
      out.push({
        idx: i,
        opt,
        score: 0,
        labelHighlightRanges: [],
        detailHighlightRanges: [],
      })
      continue
    }
    const keywords = (opt.keywords ?? []).filter(Boolean).join(' ')
    const hay = `${opt.label} ${opt.detail ?? ''} ${keywords}`.trim()
    const score = scoreMatch(hay, q)
    if (score == null) continue
    out.push({
      idx: i,
      opt,
      score,
      labelHighlightRanges: computeMatchHighlightRanges(opt.label, q),
      detailHighlightRanges: computeMatchHighlightRanges(opt.detail ?? '', q),
    })
  }
  out.sort((a, b) => b.score - a.score || a.idx - b.idx)
  return out
}

export function selectedFilteredIndex(
  filtered: readonly FilteredOption[],
  selectedIndex: number,
): number {
  const idx = filtered.findIndex((x) => x.idx === selectedIndex)
  return idx >= 0 ? idx : 0
}
