export function getFilters (allProducts, filter1, filter2) {
  return [filter1, filter2]
    .filter(Boolean)
    .map(f => {
      const [title = '', field = ''] = f.split(',')

      // Get a list of unique values for the field existing in all products.
      const options = [...(allProducts.reduce((acc, p) => new Set([...acc, p[field]]), new Set()))]
        .filter(Boolean)
        .map(v => ({ name: v, value: v }))

      // Sort values.
      options.sort((a, b) => {
        if (isNumber(a.value) && isNumber(b.value)) {
          return Number.parseFloat(a.value) - Number.parseFloat(b.value)
        }

        return a.value.localeCompare(b.value)
      })

      return { name: title, field, options }
    })
}

export function updateFiltersWithCounts (products, filters, appliedFilters) {
  // For each filter, compute counts for its options in one pass over products.
  // This reduces complexity by avoiding a per-option scan of the product list.
  for (const filter of filters) {
    const counts = computeCountsForFilter(products, filter, appliedFilters)
    filter.options = filter.options.map(o => ({ name: `${o.value} (${counts.get(o.value) || 0})`, value: o.value }))
  }
}

// Compute option counts for a filter given the searchedProducts and applied filters.
function computeCountsForFilter (products, filter, appliedFilters) {
  const counts = new Map()
  const otherApplied = appliedFilters.filter(af => af.field !== filter.field)

  for (const p of products) {
    let ok = true
    for (const af of otherApplied) {
      if (af.value && p[af.field] !== af.value) {
        ok = false
        break
      }
    }
    if (!ok) {
      continue
    }

    const val = p[filter.field]
    counts.set(val, (counts.get(val) || 0) + 1)
  }

  return counts
}

function isNumber (value) {
  return !Number.isNaN(Number.parseFloat(value))
}
