/**
 * External dependencies
 */
import removeAccents from 'remove-accents'

/**
 * Sanitizes the search input string.
 *
 * @param {string} input The search input to normalize.
 *
 * @return {string} The normalized search input.
 */
export function normalizeSearchInput(input = '') {
	// Disregard diacritics.
	input = removeAccents(input)

	// Trim & Lowercase.
	input = input.trim().toLowerCase()

	return input
}

/**
 * Get the search rank for a given pattern and a specific search term.
 *
 * @param {Object} pattern     Pattern to rank
 * @param {string} searchValue Search term
 * @return {number} A pattern search rank
 */
export function getPatternSearchRank(pattern, searchValue) {
	const normalizedSearchValue = normalizeSearchInput(searchValue)
	const normalizedTitle = normalizeSearchInput(pattern.title)

	let rank = 0

	if (normalizedSearchValue === normalizedTitle) {
		rank += 30
	} else if (normalizedTitle.startsWith(normalizedSearchValue)) {
		rank += 20
	} else {
		const searchTerms = normalizedSearchValue.split(' ')
		const hasMatchedTerms = searchTerms.every((searchTerm) =>
			normalizedTitle.includes(searchTerm)
		)

		// Prefer pattern with every search word in the title.
		if (hasMatchedTerms) {
			rank += 10
		}
	}

	return rank
}

/**
 * Filters an pattern list given a search term.
 *
 * @param {Array}  patterns    Item list
 * @param {string} searchValue Search input.
 *
 * @return {Array} Filtered pattern list.
 */
export function searchPatterns(patterns = [], searchValue = '') {
	if (!searchValue) {
		return patterns
	}

	const rankedPatterns = patterns
		.map((pattern) => {
			return [pattern, getPatternSearchRank(pattern, searchValue)]
		})
		.filter(([, rank]) => rank > 0)

	rankedPatterns.sort(([, rank1], [, rank2]) => rank2 - rank1)
	return rankedPatterns.map(([pattern]) => pattern)
}
