import { o as normalizeLowercaseStringOrEmpty } from "./string-coerce-CIXf7egm.js";
//#region src/tts/directive-facts.ts
function collectMarkdownCodeRanges(text) {
	const ranges = [];
	const addMatches = (regex) => {
		for (const match of text.matchAll(regex)) {
			if (match.index == null) continue;
			ranges.push({
				start: match.index,
				end: match.index + match[0].length
			});
		}
	};
	addMatches(/```[\s\S]*?```/g);
	addMatches(/~~~[\s\S]*?~~~/g);
	addMatches(/^(?: {4}|\t).*(?:\n|$)/gm);
	addMatches(/`+[^`\n]*`+/g);
	return ranges.toSorted((left, right) => left.start - right.start);
}
function isInsideRange(index, ranges) {
	return ranges.some((range) => index >= range.start && index < range.end);
}
function replaceOutsideMarkdownCode(text, regex, replace) {
	const codeRanges = collectMarkdownCodeRanges(text);
	return text.replace(regex, (...args) => {
		const match = String(args[0]);
		const offset = args.at(-2);
		if (typeof offset === "number" && isInsideRange(offset, codeRanges)) return match;
		return replace(match, args.slice(1, -2).map((capture) => String(capture)));
	});
}
/** Extract final-text TTS syntax into persisted facts, leaving markdown code spans unchanged. */
function extractTtsDirectiveFacts(text) {
	if (!/\[\[\s*\/?\s*tts(?:\s*:|\s*\]\])/iu.test(text)) return { cleanedText: text };
	let cleanedText = text;
	let facts;
	const markTagged = () => {
		facts ??= { tagged: true };
		return facts;
	};
	cleanedText = replaceOutsideMarkdownCode(cleanedText, /\[\[\s*tts\s*:\s*text\s*\]\]([\s\S]*?)\[\[\s*\/\s*tts\s*:\s*text\s*\]\]/gi, (_match, [inner = ""]) => {
		const next = markTagged();
		if (next.text == null) next.text = inner.trim();
		return "";
	});
	cleanedText = replaceOutsideMarkdownCode(cleanedText, /\[\[\s*tts\s*\]\]([\s\S]*?)\[\[\s*\/\s*tts\s*\]\]/gi, (_match, [inner = ""]) => {
		const next = markTagged();
		const visible = inner.trim();
		if (next.text == null) next.text = visible;
		return visible;
	});
	cleanedText = replaceOutsideMarkdownCode(cleanedText, /\[\[\s*tts\s*:\s*([^\]]+)\]\]/gi, (_match, [body = ""]) => {
		const next = markTagged();
		const tokens = body.split(/\s+/).filter(Boolean);
		let provider;
		const values = {};
		for (const token of tokens) {
			const eqIndex = token.indexOf("=");
			if (eqIndex === -1) continue;
			const rawKey = token.slice(0, eqIndex).trim();
			const rawValue = token.slice(eqIndex + 1).trim();
			if (!rawKey || !rawValue) continue;
			const key = normalizeLowercaseStringOrEmpty(rawKey);
			if (key === "provider") {
				provider = normalizeLowercaseStringOrEmpty(rawValue) || void 0;
				continue;
			}
			values[key] = rawValue;
		}
		if (provider || Object.keys(values).length > 0) {
			next.directives ??= [];
			next.directives.push({
				...provider ? { provider } : {},
				values
			});
		}
		return "";
	});
	cleanedText = replaceOutsideMarkdownCode(cleanedText, /\[\[\s*tts\s*\]\]/gi, () => {
		markTagged();
		return "";
	});
	cleanedText = replaceOutsideMarkdownCode(cleanedText, /\[\[\s*\/\s*tts(?:\s*:\s*[^\]]*)?\]\]/gi, () => {
		markTagged();
		return "";
	});
	return {
		cleanedText,
		...facts ? { facts } : {}
	};
}
//#endregion
export { extractTtsDirectiveFacts as t };
