const substitutes = {
	à: 'a',
	á: 'a',
	ä: 'a',
	å: 'a',
	ã: 'a',
	æ: 'ae',
	ç: 'c',
	è: 'e',
	é: 'e',
	ë: 'e',
	ẽ: 'e',
	ì: 'i',
	í: 'i',
	ï: 'i',
	ĩ: 'i',
	ǹ: 'n',
	ń: 'n',
	ñ: 'n',
	ò: 'o',
	ó: 'o',
	ö: 'o',
	õ: 'o',
	ø: 'o',
	œ: 'oe',
	ß: 'ss',
	ù: 'u',
	ú: 'u',
	ü: 'u',
	ũ: 'u',
	ỳ: 'y',
	ý: 'y',
	ÿ: 'y',
	ỹ: 'y',
};

export default function slugify(strings, delimiter = '-', {
	encode = false,
	removeAccents = true,
	removePunctuation = false,
	limit = 1000,
} = {}) {
	if (!strings || (typeof strings !== 'string' && !Array.isArray(strings))) {
		return strings;
	}

	const slugComponents = []
		.concat(strings)
		.filter(Boolean)
		.flatMap((string) => string
			.trim()
			.toLowerCase()
			.replace(removePunctuation && /[.,:;'"_-]/g, '')
			.match(/[A-Za-zÀ-ÖØ-öø-ÿ0-9]+/g)); // eslint-disable-line regexp/no-obscure-range -- intentional accented-Latin range for slugification

	if (!slugComponents) {
		return '';
	}

	const slug = slugComponents.reduce((acc, component, index) => {
		const accSlug = `${acc}${index > 0 ? delimiter : ''}${component}`;

		if (accSlug.length < limit) {
			if (removeAccents) {
				return accSlug.replace(/[à-ÿ]/g, (match) => substitutes[match] || ''); // eslint-disable-line regexp/no-obscure-range -- intentional accented-Latin range for slugification
			}

			return accSlug;
		}

		return acc;
	}, '');

	return encode ? encodeURI(slug) : slug;
}
