const filterImageText = (component: string | undefined): string | undefined =>
	component === "LinkableImage" ? "Image" : component;

const camelize = (str: string): string => {
	return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match, index) => {
		if (+match === 0) return ""; // or if (/\s+/.test(match)) for white spaces
		return index === 0 ? match.toLowerCase() : match.toUpperCase();
	});
};

const splitCamelCase = (value: string): string => value.replace(/([a-z])([A-Z])/g, "$1 $2");

const slugify = (value: string): string => {
	const a = "àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;";
	const b = "aaaaaaaaaacccddeeeeeeeegghiiiiiilmnnnnoooooooooprrsssssttuuuuuuuuuwxyyzzz------";
	const p = new RegExp(a.split("").join("|"), "g");

	return value
		.toString()
		.toLowerCase()
		.replace(/\s+/g, "-") // Replace spaces with -
		.replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters
		.replace(/&/g, "-and-") // Replace & with 'and'
		.replace(/[^\w-]+/g, "") // Remove all non-word characters
		.replace(/--+/g, "-") // Replace multiple - with single -
		.replace(/^-+/, "") // Trim - from start of text
		.replace(/-+$/, ""); // Trim - from end of text
};

const validateEmail = (email: string): boolean => {
	const re =
		/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
	return re.test(String(email).toLowerCase());
};

const capitalize = (s: string): string => {
	if (typeof s !== "string") return "";
	return s.charAt(0).toUpperCase() + s.slice(1);
};

const getInitials = (name?: string): string => {
	if (!name) return "";

	const rgx = new RegExp(String.raw`(\p{L}{1})\p{L}+`, "gu");
	const words: string[] = name.match(rgx) || [];
	const initials = words.reduce((previous: string[], current: string) => [...previous, current[0]], []);
	return initials.join("").slice(0, 2).toUpperCase();
};

const trimText = (text: string, length: number): string => {
	if (!text || typeof text !== "string") return "";
	const sliced = text.slice(0, length);
	return sliced.length < text.length ? `${sliced.trim()}...` : sliced;
};

const decodeEntities = (() => {
	// this prevents any overhead from creating the object each time
	const element = document.createElement("div");

	function decodeHTMLEntities(str: string) {
		if (str && typeof str === "string") {
			// strip script/html tags
			str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gim, "");
			str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gim, "");
			element.innerHTML = str;
			str = element.textContent ? element.textContent : str;
			element.textContent = "";
		}

		return str;
	}

	return decodeHTMLEntities;
})();

const isNumber = (value: string): boolean => !Number.isNaN(parseInt(value));

const getFileExtension = (fileName: string): string | null => {
	const re = /\.[0-9a-z]+$/i;
	const extension = fileName.match(re);
	return extension?.[0].slice(1) || null;
};

const splitAndJoin = (str = "", splitterIn = ",", splitterOut = ", "): string => {
	return (
		str
			?.split(splitterIn)
			.map((str: string) => str.trim())
			.filter((str: string) => str.length)
			.join(splitterOut) || ""
	);
};

const splitAndTrim = (str?: string, splitter = ","): (string | never)[] => {
	return (
		str
			?.split(splitter)
			.map((str: string) => str.trim())
			.filter((str: string) => str.length) || []
	);
};

const copyTextToClipboard = (text: string): Promise<void> => {
	if (navigator.clipboard && window.isSecureContext) {
		return navigator.clipboard.writeText(text);
	} else {
		const textArea = document.createElement("textarea");
		textArea.value = text;

		textArea.style.top = "-999999px";
		textArea.style.left = "-999999px";
		textArea.style.position = "fixed";

		document.body.appendChild(textArea);
		textArea.focus();
		textArea.select();

		return new Promise<void>((res, rej) => {
			document.execCommand("copy") ? res() : rej();
			textArea.remove();
		});
	}
};

const stripHtml = (html: string | null) => {
	if (!html || typeof html !== "string") return "";
	const tmp = document.createElement("DIV");
	tmp.innerHTML = html;
	return tmp.textContent || tmp.innerText || "";
};

/**
 * Obtiene el último segmento (slug) de una URL,
 * ignorando slashes finales o parámetros de búsqueda.
 */
const getSlugFromUrl = (urlText?: string): string | undefined => {
	if (!urlText) return "";

	try {
		const url = new URL(urlText);
		// pathname devuelve algo como "/hisco-mk-i/en/slug-final/"
		const segments = url.pathname.split("/").filter(Boolean);
		return segments.pop();
	} catch (error) {
		console.error("URL no válida", error);
		return undefined;
	}
};

export {
	filterImageText,
	splitCamelCase,
	camelize,
	slugify,
	validateEmail,
	capitalize,
	getInitials,
	trimText,
	decodeEntities,
	isNumber,
	getFileExtension,
	splitAndJoin,
	splitAndTrim,
	copyTextToClipboard,
	stripHtml,
	getSlugFromUrl,
};
