import { SortableObject, SortCriterion, Filter, range } from "@/types/datatypes"

export function inRange(value: number, range: range): boolean {
  return (range[0] === undefined || value >= range[0]) && (range[1] === undefined || value <= range[1])
}

export function rankedSorter<T extends SortableObject>(criteria: SortCriterion<T>[]) {
  return function(a: T, b: T): number {
    let result = 0
    const max = criteria.length - 1
    criteria.forEach(({prop, ascending}, index) => {
      const current = 100 ** (max - index)
      let pa: number, pb: number
      if (typeof prop === 'function') {
        pa = prop(a)
        pb = prop(b)
      } else {
        pa = a[prop]
        pb = b[prop]
      }
      if (ascending) {
        result += (pa * current - pb * current)
      } else {
        result += (pb * current - pa * current)
      }
    })
    return result
  }
}

export function multiFilter<T>(filters: Filter<T>[]) {
  return (item: T) => filters.every(filter => filter(item))
}