const offerKeywordsByCarType = {
  SEDAN: ['sedan', 'saloon'],
  PREMIUM: ['premium', 'luxury', 'executive', 'flagship', 'range rover'],
  SUV: ['suv', 'crossover', '4x4', 'off-road', 'range rover', 'prado'],
  MINIVAN: ['minivan', 'v-class'],
}

const minimumScoreByCarType = {
  SEDAN: 4,
  PREMIUM: 5,
  SUV: 5,
  MINIVAN: 4,
}

function buildOfferHaystack(offer) {
  return [
    offer?.name,
    offer?.subtitle,
    offer?.category,
    offer?.description,
    offer?.badge,
    offer?.validUntil,
    ...(Array.isArray(offer?.tags) ? offer.tags : []),
  ]
    .filter(Boolean)
    .join(' ')
    .toLowerCase()
}

function scoreOfferAgainstKeywords(offer, keywords = []) {
  const haystack = buildOfferHaystack(offer)

  return keywords.reduce((score, keyword) => {
    if (!keyword || !haystack.includes(keyword)) {
      return score
    }

    if (keyword === 'range rover') {
      return score + 3
    }

    if (keyword === 'suv' || keyword === 'premium' || keyword === 'luxury') {
      return score + 4
    }

    return score + 2
  }, 0)
}

export function matchHomeOfferToCarType(offers = [], carType = '') {
  const normalizedCarType = String(carType || '').toUpperCase()
  const keywords = offerKeywordsByCarType[normalizedCarType] || []
  const minimumScore = minimumScoreByCarType[normalizedCarType] || 4

  if (!keywords.length) {
    return null
  }

  const rankedMatches = offers
    .map((offer) => {
      const keywordScore = scoreOfferAgainstKeywords(offer, keywords)
      const merchandisingScore = (offer?.newPrice ? 1 : 0) + (offer?.badge ? 1 : 0)

      return {
        offer,
        score: keywordScore + merchandisingScore,
      }
    })
    .filter((entry) => entry.score >= minimumScore)
    .sort((left, right) => right.score - left.score)

  return rankedMatches[0]?.offer || null
}
