import type { ListingCard, SearchResponse } from "~/types/listing"

const normalize = (value?: string | null) =>
  value
    ?.normalize("NFD")
    .replace(/\p{Diacritic}/gu, "")
    .toLowerCase()
    .trim() ?? ""

const includesNormalized = (value: string | undefined, expected: string | undefined) => {
  if (!expected) {
    return true
  }

  return normalize(value).includes(normalize(expected))
}

const median = (values: number[]) => {
  if (!values.length) {
    return 0
  }

  const sorted = [...values].sort((left, right) => left - right)
  const middle = Math.floor(sorted.length / 2)

  return sorted.length % 2 === 0
    ? Math.round((sorted[middle - 1] + sorted[middle]) / 2)
    : sorted[middle]
}

export interface SearchFilters {
  make?: string
  model?: string
  version?: string
  region?: string
  transmission?: string
  fuel?: string
  minYear?: number
  maxYear?: number
  maxPrice?: number
}

export function searchListings(items: ListingCard[], filters: SearchFilters): SearchResponse {
  const filtered = items
    .filter((item) => includesNormalized(item.make, filters.make))
    .filter((item) => includesNormalized(item.model, filters.model))
    .filter((item) => includesNormalized(item.version, filters.version))
    .filter((item) => includesNormalized(item.region, filters.region))
    .filter((item) => includesNormalized(item.transmission, filters.transmission))
    .filter((item) => includesNormalized(item.fuel, filters.fuel))
    .filter((item) => (filters.minYear ? item.year >= filters.minYear : true))
    .filter((item) => (filters.maxYear ? item.year <= filters.maxYear : true))
    .filter((item) => (filters.maxPrice ? item.priceClp <= filters.maxPrice : true))
    .sort((left, right) => left.priceClp - right.priceClp)

  return {
    total: filtered.length,
    medianPrice: median(filtered.map((item) => item.priceClp)),
    cheapest: filtered[0]?.priceClp ?? 0,
    exactCount: filtered.filter((item) => item.comparisonBucket === "exacta").length,
    nearbyCount: filtered.filter((item) => item.comparisonBucket === "cercana").length,
    items: filtered
  }
}
