import type { Filter } from "@/components/reui/filters"

type FieldAccessor<T> = Record<string, (row: T) => unknown>

function matchFilter<T>(row: T, filter: Filter, accessors: FieldAccessor<T>): boolean {
  const getValue = accessors[filter.field]
  if (!getValue) return true

  const value = getValue(row)
  const vals = filter.values
  const str = (v: unknown) => String(v ?? "").toLowerCase()

  switch (filter.operator) {
    case "is":
      return vals.length > 0 && String(value) === String(vals[0])
    case "isNot":
      return vals.length === 0 || String(value) !== String(vals[0])
    case "isAnyOf":
      return vals.some((v) => String(value) === String(v))
    case "isNotAnyOf":
      return !vals.some((v) => String(value) === String(v))
    case "contains":
      return vals.some((v) => str(value).includes(str(v)))
    case "doesNotContain":
      return !vals.some((v) => str(value).includes(str(v)))
    default:
      return true
  }
}

export function applyReuiFilters<T>(
  rows: T[],
  filters: Filter[],
  accessors: FieldAccessor<T>,
): T[] {
  if (filters.length === 0) return rows
  return rows.filter((row) =>
    filters.every((f) => matchFilter(row, f, accessors)),
  )
}
